【问题标题】:Re-opening a class located in lib folder (Rails 3)重新打开位于 lib 文件夹中的类(Rails 3)
【发布时间】:2011-07-08 07:53:05
【问题描述】:

类似的问题已经被问过很多次了。但是,我的情况略有不同,在开发 Rails 3 应用程序时,我仍然要找到以下问题的干净解决方案:

我有一个位于单个文件中的 ruby​​ 代码。这段代码是一个模块MyModule,其中包含一堆类。我无法修改此代码,因为它是由外部工具自动生成的。文件名为my_module.rb,位于lib 文件夹中。这是不属于主 Web 应用程序的代码的常见位置。通过修改application.rb 中的config.autoload_paths 设置,我确保在我的一个应用控制器中访问MyModule 后它会自动加载。

现在我需要重新打开MyModule 中的一个课程。我创建了一个单独的文件some_class.rb,在其中放置了以下代码:

类 MyModule::SomeClass def some_new_method ... 结尾 结尾

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

我尝试过的事情:

  1. 将代码放入initializers 文件夹。它在生产环境中运行良好。但是,它在development 中中断,因为initiliazers 文件夹中的代码在服务器启动时加载一次,并且在每次请求时重新加载lib。因此,开发中的第一个请求工作正常,但是,后续请求失败。另外我不喜欢将代码放入initializers,因为它不是真正的初始化部分,而是业务逻辑的一部分。
  2. 将代码放入lib 文件夹也不起作用。它没有加载。只有my_module.rb 是。
  3. 将代码放入libapp 下的其他文件夹中,然后在控制器中明确requir 将其放入。再次,它在生产中工作,但在开发中失败,原因与案例 #1 中提到的相同。
  4. 我关闭了自动加载,将my_module.rbsome_class.rb 放入lib 文件夹,require将它们放入初始化程序中。我认为这是最好的方法。缺点是我仍然需要创建一个自定义初始化程序,并且代码不会延迟加载。

更新: 5. 感谢 raggi 的建议,开启自动加载后,我将require_dependency 'some_class' 放入我的控制器中。在这种情况下,some_class.rb 在开发模式下被加载到每个请求上。这是我的首选方法。但是,它仍然需要某种require :)

请记住,lib 文件夹中的文件是延迟自动加载的。只有当您使用 rails 找不到的模块或类时,Rails 才会检查该文件夹。文件名必须遵循命名约定,因此命名为my_module.rb

我想知道当两个文件都被延迟自动加载时是否有解决方案没有任何require语句。

【问题讨论】:

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


    【解决方案1】:

    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
    

    【讨论】:

      【解决方案2】:

      您是否尝试在控制器中使用 require_dependency 而不是 require?

      【讨论】:

      • 刚试过。是的,它有效。我想没有解决方案可以在没有“require”或“require_dependency”语句的情况下懒惰地自动加载这两个文件。我相信我的问题的答案是否定的。我对你的建议投了赞成票。
      【解决方案3】:

      如果您想将文件放在不同的子文件夹中,您可以将文件放在 lib 目录中,而不是延迟加载而是自动加载,在 config/application.rb 中:

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

      或者如果您只需要 lib 文件夹:

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

      【讨论】:

      • 我就是这么做的。我编辑了我的问题以提及这一点。但是,问题是 my_module.rb 是自动加载的,而 some_class.rb 不是。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-22
      • 2011-09-08
      • 2014-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多