Как я могу предварительно загрузить проблемы в инициализаторе 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, используя requireon 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
Другие вопросы по тегам