6

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

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

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

我已经尝试将它放入lib/or 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
4

1 回答 1

8

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

# 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

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

于 2020-04-23T12:56:21.127 回答