【问题标题】:Rails 4.1 unable to autoload namespaced classRails 4.1 无法自动加载命名空间类
【发布时间】: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”,否则自动加载器将无法工作)。

标签: ruby-on-rails autoloader


【解决方案1】:

好的,通过更多的挖掘,我明白发生了什么。 Rails 在PATH 中搜索类似namespace/class_name.rb 的文件路径;如果这个文件不存在,它会尝试在父模块(或类)中加载常量,这就是为什么它会递归form_model = Object

【讨论】:

    猜你喜欢
    • 2015-09-30
    • 1970-01-01
    • 2011-06-22
    • 2011-11-19
    • 2013-11-25
    • 2014-04-13
    • 1970-01-01
    相关资源
    最近更新 更多