Как я могу предварительно загрузить проблемы в инициализаторе rails, используя Rails 6/Zeitwerk?
Я работаю с инициализатором, который вносит некоторые обезьяны в патч при запуске приложения, включая некоторые проблемы приложения в стороннюю библиотеку. В принципе:
# config/initializers/my_initializer.rb
class SomeExternalLib
include MyConcern1
include MyConcern2
end
Это прекрасно работает в Rails 5.2.3, но я получил следующее сообщение об устаревании при обновлении до Rails 6:
ПРЕДУПРЕЖДЕНИЕ ОБ УСТРАНЕНИИ: При инициализации автоматически загружаются константы MyConcern1 и MyConcern2.
Возможность сделать это устарела. Автозагрузка во время инициализации будет являться условием ошибки в будущих версиях Rails.
Перезагрузка не перезагружает приложение, и поэтому код, выполненный во время инициализации, больше не запускается. Так, например, если вы перезагрузите ApplicationHelper, ожидаемые изменения не будут отражены в этом устаревшем объекте Module.
Эти автозагрузочные константы были выгружены.
Пожалуйста, ознакомьтесь с руководством "Автозагрузка и перезагрузка констант" для решения. (вызывается из /Users/myuser/code/myapp/config/environment.rb:7)
Мои проблемы находятся в приложении / контроллеры / проблемы /. После некоторого исследования я выяснил, что этот путь не был автоматически загружен, но я не могу понять, как заставить Zeitwerk - новый автозагрузчик Rails 6 - загружать это динамически. Я попытался следовать шаблону автозагрузки STI, описанному здесь, но безуспешно. Есть идеи, как устранить это предупреждение об устаревании?
0 ответов
Как описано в ответе @Glyoko, используя require
on dependencies предотвращает автозагрузку в инициализаторах. Однако это приводит к проблемам во время перезагрузки, как отметил @Puhlze в своем комментарии.
Я наткнулся на альтернативный подход, который использует Rails.configuration.to_prepare
в этом посте.
Примером может быть:
# config/initializers/my_initializer.rb
Rails.configuration.to_prepare do
class SomeExternalLib
include MyConcern1
include MyConcern2
end
end
Обратите внимание, что это выполняется перед каждым запросом в разработке, но только один раз перед загрузкой в производство.
Изменить: похоже, он также работает с перезагрузкой.
Помогло бы, если бы я прочитал сообщение об ошибке более внимательно:
Автозагрузка во время инициализации будет являться условием ошибки в будущих версиях Rails.
Обсуждение изменений здесь и руководство здесь.
Короче говоря, автозагрузка не должна выполняться в инициализаторах, и это будет прекращено. Решения могут быть: 1) не использовать вещи, которые должны быть автоматически загружены в инициализаторах (предпочтительно, очевидно), или 2) явно требовать зависимости в инициализаторах.
Так что я бы сделал:
# config/initializers/my_initializer.rb
require 'my_concern1'
require 'my_concern2'
class SomeExternalLib
include MyConcern1
include MyConcern2
end