有很多次问过类似的问题。但是,我的情况略有不同,我仍然在开发Rails 3应用程序时找到解决以下问题的干净解决方案:
我有一个位于单个文件中的ruby代码。此代码是一个模块MyModule
,其中包含一堆类。我无法修改此代码,因为它是由外部工具自动生成的。文件名为my_module.rb
,它位于lib
文件夹中。这是不属于主Web应用程序的代码的通常位置。通过修改config.autoload_paths
中的application.rb
设置,我确保在我的某个应用控制器中访问MyModule后自动加载。
现在我需要重新打开MyModule
中的一个类。我创建了一个单独的文件some_class.rb
,其中我放了以下代码:
class MyModule::SomeClass def some_new_method ... end end
我的问题是:放置此代码的最佳位置是什么?该文件的名称应该是什么?
我尝试过的事情:
initializers
文件夹。它在生产环境中工作正常。但是,它在development
中断,因为initiliazers
文件夹中的代码在服务器启动时加载一次,并在每个请求上重新加载lib
。因此,开发中的第一个请求工作正常,但后续请求失败。另外,我不喜欢将代码放入initializers
,因为它不是真正的初始化部分,而是业务逻辑的一部分。lib
文件夹也不起作用。它没有加载。只有my_module.rb
。lib
或app
下的其他文件夹中,然后在控制器中明确requir
。它再次在生产中起作用,但在开发中失败的原因与前面提到的情况#1相同。my_module.rb
和some_class.rb
放入lib
文件夹,require
将它们放入初始值设定项中。我认为这是最好的方法。缺点是我仍然需要创建一个自定义初始化程序,并且代码不会延迟加载。更新:
5.感谢raggi的建议,打开自动加载后,我将require_dependency 'some_class'
放入我的控制器中。在这种情况下,some_class.rb
在开发模式下的每个请求上加载。这是我的首选方法。但是,它仍然需要某种require
:)
请记住lib
文件夹中的文件是懒惰自动加载的。只有在使用rails无法找到的模块或类时,Rails才会检查文件夹。文件名必须遵循命名约定,因此名称为my_module.rb
。
我想知道是否存在一个解决方案,当两个文件都是懒惰地自动加载而没有任何require
语句。
答案 0 :(得分:1)
您是否在控制器中尝试require_dependency而不是require?
答案 1 :(得分:0)
如果要将文件放在不同的子文件夹中,您可以将这些文件放在lib目录中,并且不要在config / application.rb中进行延迟加载但是自动加载:
config.autoload_paths += Dir["#{config.root}/lib/**/"]
或者如果您只需要lib文件夹:
config.autoload_paths += %W(#{config.root}/lib)
答案 2 :(得分:0)
TL; DR:隐藏主线代码之外的require
。
我在尝试在开发期间在模块中创建验证器时遇到了类似的问题。当我试图解决听起来像是同样的问题时,我跑过this blog entry。
// Added to application.rb
Rails::Application.config.autoload_paths.each do |d|
Dir["#{d}/*.rb"].each do |p|
puts "Requiring '#{p}' on startup..."
require p
end
end