Как я могу расширить класс gem в Rails 6 / Zeitwerk, не нарушая перезагрузки кода?
Как мне расширить класс, который определяется драгоценным камнем, когда я использую rails 6 / zeitwerk?
Я пробовал сделать это в инициализаторе, используя require
сначала загрузить класс. Я пробовал сделать это в инициализаторе и просто сослался на класс, чтобы автозагрузка сначала загрузила его.
Но оба этих подхода нарушают автоматическую перезагрузку в режиме разработки.
Я пробовал вставить это lib/
или app/
, но это не сработает, потому что тогда класс никогда не загружается из драгоценного камня, поскольку мой новый файл находится выше в порядке загрузки.
Существует аналогичный вопрос здесь, но один конкретно спрашивает, как сделать это в инициализаторе. Меня не волнует, сделано ли это в инициализаторе или нет, я просто хочу выяснить, как это сделать каким-то образом.
Каков стандартный способ сделать что-то подобное?
У меня есть один неприятный прием, который, кажется, работает, но мне он не нравится (обновление: это тоже не работает. Перезагрузка все еще не работает):
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 ответ
Я знаю, что уже поздно, но это было настоящей болью, и кто-то может счесть это полезным, в этом примере я буду использовать папку модулей, расположенную в приложении, которая будет содержать пользовательские модули и патчи обезьян для различных драгоценных камней.
# 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, и каждый файл будет загружен вручную в конце загрузки.