当我使用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/modules"
Rails.autoloaders.main.ignore(overrides)
config.to_prepare do
Dir.glob("#{overrides}/**/*.rb").each do |override|
load override
end
end
end
end
显然这个模式叫做覆盖模式,它将防止zeitwerk自动加载你的覆盖,每个文件将在加载结束时手动加载。