Plugins Discourse et configuration Rails 6 config/initializers Question

Salut les experts des plugins Discourse,

Une petite question concernant les plugins Discourse et les initialisateurs Rails.

Si un plugin Discourse possède un répertoire nommé « config » et un sous-répertoire appelé « initializers » sous « config », l’application Rails de Discourse lit-elle tous les fichiers d’initialisation du plugin situés dans le répertoire « initializers », comme le fait Rails 6 ?

La raison de ma question est que je suis en train de développer une application « back-office » Rails 6 (uniquement Rails, sans EmberJS ni autre framework JS par-dessus) depuis zéro pour un client, et j’ai un répertoire sous initializers comme ceci :

./config/initializers/client/

… et tous les initialisateurs spécifiques au client se trouvent dans le sous-répertoire « client ».

Rails 6 lit tous les fichiers sous le répertoire standard des initialisateurs (même les sous-répertoires) ; je me demandais donc si les plugins Discourse, avec une structure de répertoire similaire pour les initialisateurs, se comporteraient comme Rails 6 et liraient tous les initialisateurs du plugin de cette manière :

./plugins/my_plugin/config/initializers/myclient/
      client_initializer1.rb
      client_initializer2.rb
      client_initializer2.rb

… sans enregistrer ces assets dans le fichier plugin.rb ?

Merci !

PS : J’ai examiné environ 10 plugins Discourse sur GitHub, et aucun de ceux que j’ai regardés ne contenait d’initialisateurs sous le répertoire config. C’est pourquoi j’ai décidé de poser la question (et mon environnement de développement Rails n’est pas configuré pour Discourse pour le moment, il est entièrement configuré pour le client).

2 « J'aime »

Je veux aussi savoir en quoi un plugin Discourse diffère d’un moteur Rails classique. J’ai simplement examiné le code source, mais je n’ai pas beaucoup compris.

Après avoir survolé cette page Ruby on Rails Guides: Configuring Rails Applications, je pense que plugin.rb est en quelque sorte la même chose. La plupart des plugins d’une taille décente l’utilisent comme point d’entrée vers la logique plutôt que comme la logique elle-même.

Oui, j’ai beaucoup lu ce guide de Rails récemment. En gros, je suis « à l’aise » avec le fonctionnement de la configuration de Rails 6 (je suis toujours en apprentissage, mais je me sens de plus en plus à l’aise chaque jour).

Je me demande simplement si nous pouvons utiliser la même structure dans un plugin Discourse (pour les initialisateurs), si Rails lira les initialisateurs dans les sous-répertoires comme il le fait dans Rails 6 ; ou si nous devons enregistrer le répertoire des initialisateurs du plugin en tant qu’« actif » de configuration (pour manque d’un meilleur terme) dans plugin.rb.

Je me suis renseigné hier sur les plugins Rails et j’ai fait quelques comparaisons.

À ma connaissance, Discourse ne lit aucun fichier Ruby autre que plugin.rb. Il lit bien les fichiers JS et de configuration. Tous les fichiers Ruby doivent être require dans plugin.rb.

3 « J'aime »

Je le pense aussi.

Vous chargez tous les fichiers Ruby supplémentaires dont vous avez besoin depuis plugin.rb.

Voici un exemple issu du plugin Follow :

1 « J'aime »

C’est à peu près l’impression que j’ai eue en parcourant plusieurs plugins Discourse sur GitHub.

Il semble que Discourse ne lise que plugin.rb et que nous devions charger tous les autres fichiers Ruby dont nous pourrions avoir besoin, comme les initialisateurs, dans plugin.rb.

Cependant, j’espérais me tromper et qu’il existe une intégration « plus profonde » entre les plugins Discourse et Rails ; car j’ai été très gâté par la qualité de Rails 6.

Merci de confirmer également.

1 « J'aime »

Je pense qu’il devrait être possible d’exiger du code d’initialisation dans plugin.rb également.
Avez-vous essayé ceci dans plugin.rb

Rails.application.config.before_initialize do
  # le code d'initialisation va ici
end

Oui, ce n’est pas un problème d’appeler et de charger les initialisateurs dans plugin.rb.

La raison de ma question est que je suis actuellement en train d’écrire une application Rails 6 assez volumineuse pour une entreprise, en convertissant leurs scripts de bureau hérités (sur plusieurs décennies) vers une application Rails. Pour ajouter des initialisateurs, j’ai simplement un sous-répertoire sous config/initializers (dans Rails) et tous mes fichiers d’initialisation sont inclus si élégamment, sans avoir besoin d’écrire le moindre code pour les inclure dans Rails.

Merci pour toutes vos réponses. C’est très apprécié !

1 « J'aime »

Oui, j’adorerais que les avantages de Rails soient portés vers les plugins Discourse. L’un de mes favoris personnels serait de pouvoir recharger à chaud les fichiers Ruby sans redémarrer le serveur.

1 « J'aime »

C’est exactement à cela que sert reloadable_patch. Si vous enveloppez les modifications de classes Ruby dans reloadable_patch, elles devraient se recharger à chaud !

1 « J'aime »

Puis-je envelopper tout le fichier plugin.rb dedans pour le développement ? Plus sérieusement, jusqu’où pouvons-nous aller avec cela ?

De plus, ajouter de nouveaux fichiers ou modifier des fichiers yml nécessite un redémarrage du serveur, n’est-ce pas ?

2 « J'aime »

Vous ne devriez pas avoir à effectuer un reloadable_patch pour tout. De nombreuses méthodes définies dans instance.rb pour faciliter le développement de plugins utilisent reloadable_patch en interne, comme add_to_serializer.

Idéalement, notre API de plugin est suffisamment bonne pour que vous n’ayez pas à effectuer une quantité démesurée de reloadable_patch.

Oui, c’est exact. Je me demande s’il est possible de faire quelque chose concernant les modifications des fichiers yml ; cela m’agace personnellement.

3 « J'aime »

C’est vrai. Je ne savais pas que reloadable_patch était destiné à prendre en charge le rechargement en direct. Je peux penser à de nombreux cas d’usage autres que ceux où Discourse l’utilise déjà, c’est-à-dire :

reloadable_patch do
 require 'x/y/z'
end

ou des patches monkey.

1 « J'aime »

Je pense que supprimer ou ajouter une telle fonction poserait toujours problème, car reloadable_patch est appelé à l’intérieur de la fonction.

Dans tous les cas, cela aide énormément.

1 « J'aime »

J’ai commencé à examiner le rechargement à chaud des modifications YAML, et cela fonctionne effectivement. Les plugins peuvent perturber ce rechargement à chaud s’ils n’utilisent pas correctement reloadable_patch, mais une fois que tous vos plugins peuvent se recharger en toute sécurité, vos modifications YAML le pourront aussi.

4 « J'aime »

Ce serait toutefois très utile si vous pouviez décrire les étapes exactes pour utiliser un patch rechargeable.

Voici ce que j’ai essayé, sans grand succès (je manque certainement quelque chose) :

after_initialize do
    add_to_serializer(:topic_view, :check, false) do
        puts 'nocheck'
    end
end

Une fois le serveur démarré, même si je remplace nocheck par check, il affiche toujours nocheck après avoir rechargé la route du sujet.

after_initialize do
    reloadable_patch do |plugin|
        puts 'nocheck'
    end
end

Toujours pas de succès lorsque je recharge une page après avoir modifié la chaîne dans puts.

Je suppose que je vous ai induit en erreur dans les messages ci-dessus. reloadable_patch est utile pour le développement de Discourse, mais @david en a très bien expliqué l’utilisation :


Tout ce qui se trouve dans le bloc after_initialize de plugin.rb n’est chargé que au démarrage de l’application, et non lors des rechargements ultérieurs.

Donc, en supposant que vous souhaitiez ajouter quelque chose au sérialiseur de l’utilisateur. Le comportement normal serait le suivant :

Au démarrage :

  • Discourse charge user_serializer.rb
  • Discourse charge plugin.rb, qui contient une surcharge pour user_serializer

Au rechargement :

  • Discourse recharge user_serializer.rb
  • (la correction de plugin.rb n’est pas rechargée, la surcharge du plugin est perdue)

Avec notre système reloadable_patch :

Au démarrage :

  • Discourse charge user_serializer.rb
  • Discourse charge plugin.rb et enregistre le reloadable_patch pour le sérialiseur de l’utilisateur
  • Les correctifs rechargeables sont exécutés

Au rechargement :

  • Discourse recharge user_serializer.rb
  • Les correctifs rechargeables sont exécutés
  • (yay, la surcharge du plugin fonctionne toujours)
6 « J'aime »

Cela décrit une propriété fondamentale de Rails, qui n’est pas spécifique à Discourse.

Dans Rails, tous les initialisateurs ne sont chargés qu’au démarrage de Rails. Ainsi, tout plugin exécutant du code basé sur un initialiseur, comme after_initialize, ne s’exécutera qu’au démarrage ou au redémarrage de Rails (corrigez-moi si je me trompe).

La raison pour laquelle je connais cela est que je développe actuellement une application Rails pour un client et que j’ai écrit de nombreux initialisateurs pour diverses tâches (valeurs booléennes, tableaux statiques, etc.). Dans chaque cas, si nous modifions du code dans un initialiseur Rails, il est nécessaire de redémarrer Rails (“Control c, rails s en mode dev”) pour que les nouvelles valeurs des initialisateurs soient prises en compte par l’application Rails.

Veuillez me corriger si je me trompe ! Merci.

Parfois, je pense que cela peut prêter à confusion pour certains développeurs de plugins Discourse, en particulier ceux qui travaillent principalement sur des plugins Discourse et non sur des applications Rails en général, lorsque nous écrivons « Discourse fait ceci » ou « Discourse fait cela », alors que ce que nous décrivons réellement est une fonction ou une propriété fondamentale de Rails, pas nécessairement spécifique à Discourse en soi.

Rails 6 lit tous les fichiers du répertoire config/initializers (et de tous les sous-répertoires config/initializers) uniquement au démarrage de Rails. De même (je ne suis pas à 100 % sûr pour les plugins), un plugin Discourse dont le code dépend de after_initialize sera (confirmez-le s’il vous plaît) chargé par l’application Rails uniquement au démarrage ou au redémarrage de Rails, car il s’agit d’une propriété fondamentale du processus de démarrage de Rails.

Je suppose que tout le monde ici qui travaille sur Rails le sait déjà. Je commence seulement à connaître ces détails (et je sens que j’ai encore un long chemin à parcourir pour devenir un expert) ; car je travaille quotidiennement sur une application Rails en ce moment, et par ailleurs, je regrette maintenant de ne pas avoir commencé à travailler avec Rails il y a dix ans, car venant d’un background de développement LAMP, je trouve Rails bien supérieur (facile et agréable à utiliser).

Je suis devenu un grand fan de Rails cette année et je suis très reconnaissant envers Discourse de m’avoir lancé sur cette voie.

Encore une fois, veuillez me corriger si je me trompe ! Merci. J’essaie de devenir plus expert en Rails.

6 « J'aime »

Oui ! C’est exact, tout comme votre compréhension des initialisateurs de Rails.

Je suis aussi un grand fan de Rails :slight_smile:

7 « J'aime »