Namespaced模块和Rails 3.1.3 autoload_path

Yeg*_*eps 7 ruby ruby-on-rails

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

在/app/models/car.rb中

class Car
 include Search::Car
end
Run Code Online (Sandbox Code Playgroud)

在/lib/search/car.rb中

module Search
  module Car
    include ActiveSupport::Concern
    # methods in here
  end
end
Run Code Online (Sandbox Code Playgroud)

在/config/application.rb中

config.autoload_paths += Dir["#{config.root}/lib/**/"]
config.autoload_paths += Dir["#{config.root}/lib/search/*"]
Run Code Online (Sandbox Code Playgroud)

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

Expected #{Rails.root}/lib/search/car.rb to define Car
Run Code Online (Sandbox Code Playgroud)

问题的性质表明它与以下内容有关:

/config/environments/development.rb

config.cache_classes = false
Run Code Online (Sandbox Code Playgroud)

我也尝试将文件search.rb直接放在/lib我定义的位置Search:

module Search
  # Put shared methods here
end
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

更新:

好吧,事实证明,如果我重新命名Search::Car,以Search::CarSearch它的工作原理.是否不可能在不同的范围内具有相同名称的模块/类?

Iur*_* G. 4

该错误来自您的 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
Run Code Online (Sandbox Code Playgroud)

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

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