Cannot load Ruby Model under a namespace -
i have namespaced post controller below
class admin::blog::postscontroller < admin::basecontroller end
and namespaced model follows.
class blog::post < activerecord::base end
but when try access model inside index action of post controller below
def index @posts = blog::post.where(:foo_id => params[:id]).paginate(:page => params[:page], :per_page => 20) end
i following error
loaderror @ /admin/blog/posts expected/app/models/blog/post.rb define post
but when move model admin::blog::post namespace blog::post works.
i'm bit confused , not able going on this. required controller , model should present in same namespace ?
following snippet routes.rb
namespace :admin namespace :blog resources :posts resources :categories end end
blog module snippet
module blog def self.table_name_prefix 'blog_' end end
preloading controllers , models
config.autoload_paths += dir["#{rails.root}/app/models/**/**"] config.autoload_paths += dir["#{rails.root}/app/controllers/**/**"] config.autoload_paths += dir["#{config.root}/app/helpers/**/**"] config.autoload_paths += dir["#{config.root}/app/tags/**/**"] config.autoload_paths += %w[ #{rails.root}/app/extensions #{rails.root}/app/modules #{rails.root}/app/drops #{rails.root}/app/filters #{rails.root}/app/mailers ]
this caused rails' autoloader. when doing :
module foo class bar end end
and trying use foo::bar
, autoloader first tries locate app/models/foo/bar.rb
. file loaded, , module foo
defined here (albeit module containing solely bar
) autoloader never attempts load app/models/foo.rb
.
this should happen in development mode, in production mode of files require
'd on startup.
there 2 workarounds afaik :
require module
using require_dependency
:
require_dependency 'foo' module foo class bar end end
this imho right solution, not break constant lookup, bit annoying have add require statement on top of each namespaced file.
create custom active record base
this solution doesn't rely on autoloading. set models inherit following, instead of activerecord::base
directly:
class customactiverecordbase < activerecord::base self.abstract_class = true # if no table name prefix has been defined, include namespace/module # table name prefix, e.g., blog:: -> blog_ def self.table_name # if table_name_prefix has been defined, follow default behaviour return super if full_table_name_prefix.present? # find prefix, e.g., blog::post -> 'blog', user -> '' prefix = model_name.name.deconstantize.underscore # if no prefix, follow default behaviour return super unless prefix.present? # otherwise add prefix underscore "#{prefix}_#{super}" end end
then there no need define self.table_name_prefix
in blog.rb
.
this could done monkey-patching activerecord::base
, interferes other classes, such activerecord::schemamigration
, doesn't have table prefix.
note :
this bug seems have been resolved in rails 4. used second workaround lot while on rails 3, i've tried reproduce bug in rails 4 , not show anymore. think modified way autoloader works... more info, see the rails guides on autoloading , reloading constants
Comments
Post a Comment