2012-09-17 156 views
4

冲突的我已经在轨3.2.6两类:在模型Rails的命名空间模型与非命名空间模型

  • 类Foo/foo.rb(在表FOOS,每默认)
  • 类酒吧::美孚在模型/酒吧/ foo.rb(设置self.table_namebar_foos

当我进入控制台,我得到:

> Bar::Foo 
=> Bar::Foo(id: ...) 
> Foo # or ::Foo 
LoadError: expected models/bar/foo.rb to define Foo 

怎么了?

回答

5

我们在IRC中解决了这个问题,但核心问题是有一个config.autoload_paths glob集,其中包含models/**作为加载路径。

Rails的自动加载器迭代加载路径,并使用常量名称。一旦找到存在的文件,它会尝试加载它,然后在常量不可用时抛出异常。

那么,发生了什么事是Rails的有像负载路径列表:

/models/bar/ 
/models/ 

它是迭代的路径,并将在/models/bar/foo.rb找到匹配,它然后负载(这使得Bar::Foo可用,但不是Foo),然后抛出异常,因为Foo不可用。

这种情况下的解决方案是删除autoload_paths设置,以便Rails找不到加载根级别常量的错误文件。

2

原来,这条线在配置/ applications.rb是问题:

config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')] 

有了明确设置自动加载,Rails的糊涂了;而不是通过适当的命名空间来查看模型/它,它查看了它拥有的第一个自动加载文件(错误地是models/bar/foo.rb),并发现它没有定义Foo(它定义Bar ::富)。

很明显,Rails 3已经知道要在名称空间模型的models/subdirs中查找。

感谢freenode上的AntiarC#RubyOnRails帮助解决这个问题。