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



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

我已经尝试在初始化器中使用require来首先加载类。我尝试过在初始化器中执行此操作,只引用该类,让自动加载首先加载它。

但这两种方法都打破了开发模式中的自动重载。

我试着把它放在lib/app/中,但这不起作用,因为这样类就永远不会从gem中加载,因为我的新文件在加载顺序中更高。

这里也有一个类似的问题,但有一个问题专门问如何在初始化器中做到这一点。我不在乎它是否在初始化器中完成,我只想弄清楚如何以某种方式完成。

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

我确实有一个讨厌的黑客,似乎正在工作,但我不喜欢它(更新:这也不工作。重新加载仍然中断(:

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

我知道迟到了,但这真的很痛苦,有些人可能会觉得这很有帮助,在这个例子中,我将使用应用程序上的模块文件夹,其中包含各种宝石的自定义模块和猴子补丁。

# config/application.rb
...
module MyApp
class Application < Rails::Application
config.load_defaults(6.0)
overrides = "#{Rails.root}/app/overrides"
Rails.autoloaders.main.ignore(overrides)
config.to_prepare do
Dir.glob("#{overrides}/**/*_override.rb").each do |override|
load override
end
end
end
end

显然,这种模式被称为覆盖模式,它将阻止zeitwerk自动加载覆盖,并且每个文件都将在加载结束时手动加载。

RubyonRails指南中也介绍了这种模式:https://edgeguides.rubyonrails.org/engines.html#overriding-型号和控制器

最新更新