【发布时间】:2014-06-08 22:08:26
【问题描述】:
我已经为嵌套资源的 url 做了一个助手
# app/urls/url.rb
module Url; end
然后
# app/urls/base.rb
module Url
class Base
# common code
end
end
当我尝试从Url::Base 继承时,出现LoadError:
Unable to autoload constant Base, expected xxx/app/urls/base.rb to define it
我已经对其进行了一些调试,文件来源正确并且类已加载,但检查存在错误。错误似乎诞生于ActiveSupport::Dependencies#const_missing,当它通过Object 作为from_mod(Url。
试试这个:
Url::Base # Raise LoadError
Url::Base # Works!
我仍然无法理解为什么 const_missing 触发 Object 而不是 Url... 有什么帮助?我做错了什么?
编辑
好的,通过更多的挖掘,我明白发生了什么。 Rails 在PATH 中搜索像namespace/class_name.rb 这样的文件路径;如果这个文件不存在,它会尝试在父模块(或类)中加载常量,这就是为什么它会递归form_model = Object。
【问题讨论】:
-
如何加载 'app/urls' 中的内容?另外:你确定那是确切的错误吗?因为你的模块是单数,而文件夹是复数。
-
如果我没记错的话,因为 Rails 3 'app/' 下的每个文件夹都包含在 PATH 中,所以是的,它是正确的。您还可以在异常消息中看到正确的文件来源,这就是为什么如果您再次调用它,它会起作用
-
我遇到了同样的错误。更好的是,如果我将课程(例如您的
urls课程)移动到lib文件夹,一切正常:( -
@AndréHerculano 在我的情况下,错误是在路径中使用“urls”而不是“url”。它必须反映命名空间,所以如果你的类的全名是“Example::Test”,它的路径必须是“app/example/test.rb”。这是不是更清楚一点? :)
-
如果您不想在 app/lib 下移动东西(因为可能 lib 包含杂项类),您可以创建一个目录,例如 app/namespaced/ 并将所有内容嵌套在那里 - 例如。 app/namespaced/url/base.rb (我认为您需要在目录名称中使用“url”而不是“urls”,否则自动加载器将无法工作)。