在 Rails 中扩展模块

Extending Modules in Rails

我的 lib 文件夹中有一个文件夹,其中包含一个模块和一些子模块。简化后看起来像这样:

文件夹结构

lib/bottles  
lib/bottles/bottles.rb  
lib/bottles/caps.rb  

bottles.rb

module Bottles
  def hello_bottles
    puts "Hello Bottles"
  end
end

caps.rb

module Bottles
  module Caps
    def hello_caps
      puts "Hello Caps"
    end
  end
end

此外,在 config/application.rb 中,我有以下行:

config.autoload_paths += %W(#{config.root}/lib)

我在 class 中包含模块及其子模块,如下所示:

class MyClass
  extend Bottles
  extend Bottles::Caps
end

问题是调用 MyClass.hello_caps 工作正常并打印 "Hello Caps",但是调用 MyClass.hello_bottles 给我一个未定义的方法错误:

NoMethodError: undefined method 'hello_bottles' for MyClass

扩展顶级 Bottles 模块的正确语法和配置是什么,以便我可以将其方法用作 class 方法?

问题出在 Rails 自动加载我认为的东西的方式上。因为它会在位于 <load_path>/bottles.rb 的文件中查找顶级模块,所以找不到它(这就是 caps 起作用的原因,因为它会在目录中查找与顶级模块同名的所有子模块) .所以解决方案是将 bottles.rb 文件向上移动一个目录级别。

Rails 期待不同的文件结构,像这样:

lib/bottles.rb  
lib/bottles/caps.rb

http://guides.rubyonrails.org/autoloading_and_reloading_constants.html#autoloading-algorithms-relative-references