我正在使用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
答案 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 )