【问题标题】:Namespaced modules and Rails 3.1.3 autoload_path命名空间模块和 Rails 3.1.3 autoload_path
【发布时间】:2012-02-16 22:25:36
【问题描述】:

我在为模型中包含的模块命名时遇到了一些麻烦。

在 /app/models/car.rb 中

class Car
 include Search::Car
end

在 /lib/search/car.rb 中

module Search
  module Car
    include ActiveSupport::Concern
    # methods in here
  end
end

在 /config/application.rb 中

config.autoload_paths += Dir["#{config.root}/lib/**/"]
config.autoload_paths += Dir["#{config.root}/lib/search/*"]

奇怪的是,当我启动服务器时,我没有直接收到任何错误。 但是,如果我在一段时间后刷新浏览器,我会收到此错误:

Expected #{Rails.root}/lib/search/car.rb to define Car

问题的性质表明它与以下方面有关:

/config/environments/development.rb

config.cache_classes = false

我还尝试将文件search.rb 直接放在我定义Search/lib 中:

module Search
  # Put shared methods here
end

我做错了什么?

更新:

好的,事实证明,如果我将 Search::Car 重命名为 Search::CarSearch 它可以工作。 不能在不同的范围内拥有同名的模块/类吗?

【问题讨论】:

  • 您可以在不同的范围内拥有同名的模块/类,但是当您使用模块 Car 方法时,您应该指定范围,以消除歧义。
  • 您好,感谢您的评论。我也是这么想的,但是好像不行。知道为什么我会收到错误吗?

标签: ruby-on-rails ruby


【解决方案1】:

错误来自您的 autoload_paths。 config.autoload_paths += Dir["#{config.root}/lib/**/"] 会将所有目录及其子目录添加到 lib 目录下。这意味着您要告诉 rails 自动加载 lib/search/ 目录,因此该目录下的 car.rb 应该定义 Car 而不是 Search::Car。为了让 rails 期望 lib/search/car.rb 定义 Search::Car,您需要自动加载 lib/ 目录而不是 lib/search。如果您将自动加载更改为 config.autoload_paths += Dir["#{config.root}/lib/"] 并使用以下代码将 search.rb 放入 lib/:

module Search
  require 'search/car'
end

那么 rails 会理解并期望 lib/search/car.rb 确实定义 Search::Car 并且在代码的其他位置引用 Car 模块/类不会引用这个 car.rb。

您应该删除此行(您应该只对 lib 目录进行自动加载): config.autoload_paths += Dir["#{config.root}/lib/search/*"]

【讨论】:

    猜你喜欢
    • 2014-01-26
    • 2011-05-23
    • 1970-01-01
    • 2012-07-08
    • 2018-12-10
    • 1970-01-01
    • 2011-01-22
    • 2015-09-09
    • 1970-01-01
    相关资源
    最近更新 更多