web-dev-qa-db-fra.com

Comment précharger les problèmes dans un initialiseur Rails en utilisant Rails 6 / Zeitwerk?)

Je travaille avec un initialiseur qui effectue des correctifs de singe au démarrage de l'application en incluant des problèmes d'application dans une bibliothèque tierce. Fondamentalement:

# config/initializers/my_initializer.rb

class SomeExternalLib
  include MyConcern1
  include MyConcern2
end

Cela fonctionne très bien dans Rails 5.2.3, mais j'ai reçu le message de dépréciation suivant lors de la mise à niveau vers Rails 6:

AVERTISSEMENT DE DÉPRÉCIATION: l'initialisation a chargé automatiquement les constantes MyConcern1 et MyConcern2.

Pouvoir le faire est obsolète. Le chargement automatique lors de l'initialisation sera une condition d'erreur dans les futures versions de Rails.

Le rechargement ne redémarre pas l'application et le code exécuté lors de l'initialisation ne s'exécute donc pas à nouveau. Ainsi, si vous rechargez ApplicationHelper, par exemple, les modifications attendues ne seront pas reflétées dans cet objet Module périmé.

Ces constantes chargées automatiquement ont été déchargées.

Veuillez consulter le guide "Constantes de chargement automatique et de rechargement" pour les solutions. (appelé à partir de /Users/myuser/code/myapp/config/environment.rb:7)

Mes préoccupations sont dans l'application/contrôleurs/préoccupations /. Après une enquête, j'ai compris que ce chemin n'était pas chargé automatiquement, mais je ne sais pas comment faire pour que Zeitwerk - le nouveau chargeur automatique de Rails 6 - charge cela dynamiquement. J'ai essayé de suivre le modèle de chargement automatique STI décrit ici , mais pas de chance. Vous avez une idée de la façon de répondre à cet avertissement de dépréciation?

10
Glyoko

Comme décrit par la réponse de @ Glyoko, l'utilisation de require sur les dépendances empêche le chargement automatique dans les initialiseurs. Cependant, cela entraîne des problèmes lors du rechargement, comme @Puhlze l'a mentionné dans son commentaire.

Je suis tombé sur une autre approche qui utilise Rails.configuration.to_prepare in ce message .

Un exemple serait:

# config/initializers/my_initializer.rb

Rails.configuration.to_prepare do
  class SomeExternalLib
    include MyConcern1
    include MyConcern2
  end
end

Notez que cela s'exécute avant chaque demande en développement mais une seule fois avant un chargement rapide en production.

Edit: il semble également fonctionner avec le rechargement.

4
Joseph Siefers

Serait utile si je lis le message d'erreur de plus près:

Le chargement automatique pendant l'initialisation sera une condition d'erreur dans les futures versions de Rails.

La discussion pour le changement est ici et le guide est ici .

En bref, le chargement automatique ne doit pas être effectué dans les initialiseurs, et cela va être supprimé progressivement. Les solutions sont soit 1) Ne pas utiliser des éléments qui doivent être chargés automatiquement dans les initialiseurs (de préférence, évidemment), ou 2) exiger explicitement des dépendances dans les initialiseurs.

Je ferais donc:

# config/initializers/my_initializer.rb

require 'my_concern1'
require 'my_concern2'

class SomeExternalLib
  include MyConcern1
  include MyConcern2
end
4
Glyoko