在Rails中需要整个目录树的好方法是什么?

时间:2012-04-16 00:35:43

标签: ruby-on-rails ruby ruby-on-rails-3

我正在使用Rails 3.2.2并希望以递归方式加载某个目录中的所有代码。例如:

[Rails root]/lib/my_lib/my_lib.rb
[Rails root]/lib/my_lib/subdir/support_file_00.rb
[Rails root]/lib/my_lib/subdir/support_file_01.rb
...    

基于谷歌搜索,我试过:

config.autoload_paths += ["#{Rails.root.to_s}/lib/my_lib/**"]
config.autoload_paths += ["#{Rails.root.to_s}/lib/my_lib/**/"]
config.autoload_paths += ["#{Rails.root.to_s}/lib/my_lib/**/*"]
config.autoload_paths += ["#{Rails.root.to_s}/lib/my_lib/{**}"]
config.autoload_paths += ["#{Rails.root.to_s}/lib/my_lib/{**}/"]

这些都没有加载任何代码,我得到“未初始化的常量”错误。

这会直接在/my_lib/中加载文件,但不会在子目录中加载文件:

config.autoload_paths += ["#{Rails.root.to_s}/lib/my_lib"]

更新

感谢您的评论。

我把它放在我的application.rb

Dir["#{Rails.root.to_s}/lib/**/*.rb"].each { |file| config.autoload_paths += [file] }

应用程序启动但我的库中声明的类不可用:

> MyClass
NameError: uninitialized constant MyClass

4 个答案:

答案 0 :(得分:8)

autoload_paths和朋友只有在给定文件或给定目录中的文件根据rails命名方案命名时才能工作。

e.g。如果文件some_class.rb被赋予autoload_paths,它会触发文件以声明类SomeClass,并设置一些魔法来对SomeClass引用该文件进行任何引用-the-飞。

因此,如果您希望只在需要时加载每个文件,那么您必须相应地命名文件,并且每个类都有一个文件。

如果您乐意在rails启动时加载目录树中的所有文件,则可以执行以下操作:

Dir.glob("/path/to/my/lib/**/*.rb").each { |f| require f }

以上内容将读取.rb中的每个/path/to/my/lib文件及其下的所有目录。

答案 1 :(得分:2)

自动加载路径必须是显式路径 - 它们不能包含文件globs(通配符)。

因此,您必须先进行扩展:

Dir["#{Rails.root.to_s}/lib/my_lib/**/*.rb"].each do |path|
  config.autoload_paths += [path]
end

答案 2 :(得分:2)

这是一种添加整个lib目录的简单方法,该目录不需要.each,并且比其他答案更简单

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

请参阅@Michael Slade's answer,以获取有关自动加载功能的完整摘要

答案 3 :(得分:0)

你也可以试试。

application.rb:

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