7

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

4 回答 4

11

autoload_paths和朋友只有在给定文件或给定目录中的文件根据rails命名约定命名时才起作用。

例如,如果some_class.rb给定一个文件autoload_paths,它会期望该文件声明一个类SomeClass,并设置一些魔术来进行任何引用以SomeClass即时加载该文件。

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

如果您乐于在 rails 启动时加载目录树中的所有文件,您可以这样做:

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

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

于 2012-04-16T03:08:49.960 回答
3

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

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

请参阅@Michael Slade 的回答,了解自动加载的作用

于 2018-08-03T16:48:00.410 回答
2

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

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

Dir["#{Rails.root.to_s}/lib/my_lib/**/*.rb"].each do |path|
  config.autoload_paths += [path]
end
于 2012-04-16T01:15:34.957 回答
0

你也可以试试。

应用程序.rb:

  config.autoload_paths += %W( #{config.root}/app/model/super_model )
  config.autoload_paths += %W( #{config.root}/lib )
于 2012-04-16T12:01:56.333 回答