如何在Rails 6 / Zeitwerk中扩展gem类而不中断代码重新加载?

时间:2019-11-14 21:21:48

标签: ruby-on-rails zeitwerk

在使用rails 6 / zeitwerk时,如何扩展gem定义的类?

我尝试在初始化器中使用require进行此操作,以首先加载该类。 我尝试在初始化程序中进行操作,只是引用该类以让自动加载首先加载它。

但是这两种方法都破坏了开发模式下的自动重装。

我尝试将其放在lib/app/中,但这不起作用,因为那样一来该类就不会从gem加载,因为我的新文件在加载顺序上更高

有一个类似的问题here,但具体询问了如何在初始化程序中执行此操作。我不在乎是否在初始化程序中完成,我只想弄清楚如何做。

做这样的事情的标准方法是什么?

我确实有一个令人讨厌的骇客,似乎在起作用,但我不喜欢它(更新:这也不起作用。重新加载仍然无效):

the_gem_root = $LOAD_PATH.grep(/the_gem/).grep(/models/).first
require("#{the_gem_root}/the_gem/some_model")

class SomeModel

    def my_extension
        ...
    end

end

1 个答案:

答案 0 :(得分:4)

我知道来晚了,但这确实是一个痛苦,有人会发现它很有帮助,在此示例中,我将使用位于应用程序上的modules文件夹,其中将包含用于各种宝石的自定义模块和猴子补丁。

# config/application.rb
...
module MyApp
  class Application < Rails::Application
    config.load_defaults(6.0)

    overrides = "#{Rails.root}/app/modules"

    Rails.autoloaders.main.ignore(overrides)

    config.to_prepare do
      Dir.glob("#{overrides}/**/*.rb").each do |override|
        load override
      end
    end
  end
end

显然,此模式称为“覆盖”模式,它将防止zeitwerk自动加载覆盖,并且每个文件将在加载结束时手动加载。