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

Popular posts from this blog

android - Gradle sync Error:Configuration with name 'default' not found -

java - Andrioid studio start fail: Fatal error initializing 'null' -

html - jQuery UI Sortable - Remove placeholder after item is dropped -