重新打开位于lib文件夹中的类(Rails 3)

时间:2011-03-03 19:48:24

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

有很多次问过类似的问题。但是,我的情况略有不同,我仍然在开发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

我的问题是:放置此代码的最佳位置是什么?该文件的名称应该是什么?

我尝试过的事情:

  1. 将代码放入initializers文件夹。它在生产环境中工作正常。但是,它在development中断,因为initiliazers文件夹中的代码在服务器启动时加载一次,并在每个请求上重新加载lib。因此,开发中的第一个请求工作正常,但后续请求失败。另外,我不喜欢将代码放入initializers,因为它不是真正的初始化部分,而是业务逻辑的一部分。
  2. 将代码放入lib文件夹也不起作用。它没有加载。只有my_module.rb
  3. 将代码放入libapp下的其他文件夹中,然后在控制器中明确requir。它再次在生产中起作用,但在开发中失败的原因与前面提到的情况#1相同。
  4. 我关闭了自动加载功能,将my_module.rbsome_class.rb放入lib文件夹,require将它们放入初始值设定项中。我认为这是最好的方法。缺点是我仍然需要创建一个自定义初始化程序,并且代码不会延迟加载。
  5. 更新: 5.感谢raggi的建议,打开自动加载后,我将require_dependency 'some_class'放入我的控制器中。在这种情况下,some_class.rb在开发模式下的每个请求上加载。这是我的首选方法。但是,它仍然需要某种require:)

    请记住lib文件夹中的文件是懒惰自动加载的。只有在使用rails无法找到的模块或类时,Rails才会检查文件夹。文件名必须遵循命名约定,因此名称为my_module.rb

    我想知道是否存在一个解决方案,当两个文件都是懒惰地自动加载而没有任何require语句。

3 个答案:

答案 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