Étant donné que la dernière version de Rails 3 n'est plus à chargement automatique des modules et des classes de lib, quelle serait la meilleure façon de les charger?
De github:
A few changes were done in this commit: Do not autoload code in *lib* for applications (now you need to explicitly require them). This makes an application behave closer to an engine (code in lib is still autoloaded for plugins);
app/lib
.Source: Rails 3 Quicktip: Autoload lib directory incluant tous les sous-répertoires, évitez le chargement paresseux
Veuillez noter que les fichiers contenus dans le dossier lib ne sont chargés qu'au démarrage du serveur. Si vous souhaitez avoir la possibilité de recharger automatiquement ces fichiers, lisez: Rails 3 Quicktip: Recharger automatiquement les dossiers lib en mode développement . Sachez que cela n'est pas destiné à un environnement de production car le rechargement permanent ralentit la machine.
la source
La magie du chargement automatique
Je pense que l'option contrôlant les dossiers à partir desquels se fait le chargement automatique a été suffisamment couverte dans d'autres réponses. Cependant, dans le cas où quelqu'un d'autre a des problèmes de chargement alors qu'ils ont vu leurs chemins de chargement automatique modifiés comme requis, cette réponse essaie d'expliquer quelle est la magie derrière ce chargement automatique.
Donc, quand il s'agit de charger des choses à partir de sous-répertoires, il y a un piège ou une convention que vous devez connaître. Parfois, la magie Ruby / Rails (cette fois principalement Rails) peut rendre difficile de comprendre pourquoi quelque chose se passe. Tout module déclaré dans les chemins de chargement automatique ne sera chargé que si le nom du module correspond au nom du répertoire parent. Donc, si vous essayez de mettre
lib/my_stuff/bar.rb
quelque chose comme:Il ne sera pas chargé automatiquement. Là encore , si vous renommez le répertoire parent pour
foo
ainsi l' hébergement de votre module à la voie:lib/foo/bar.rb
. Ce sera là pour vous. Une autre option consiste à nommer le fichier que vous souhaitez charger automatiquement par le nom du module. De toute évidence, il ne peut y avoir qu'un seul fichier de ce nom. Dans le cas où vous avez besoin de diviser vos fichiers en plusieurs fichiers, vous pouvez bien sûr utiliser ce fichier pour exiger d'autres fichiers, mais je ne le recommande pas, car alors en mode développement et que vous modifiez ces autres fichiers, Rails ne peut pas le faire automatiquement. rechargez-les pour vous. Mais si vous voulez vraiment, vous pouvez avoir un fichier par le nom du module qui spécifie alors les fichiers réels nécessaires pour utiliser le module. Vous pouvez donc avoir deux fichiers:lib/my_stuff/bar.rb
etlib/my_stuff/foo.rb
et le premier étant le même que ci-dessus et le dernier contenant une seule ligne:require "bar"
et cela fonctionnerait tout de même.PS Je me sens obligé d'ajouter une chose plus importante. Ces derniers temps, chaque fois que je veux avoir quelque chose dans le répertoire lib qui doit être chargé automatiquement, j'ai tendance à penser que si c'est quelque chose que je développe spécifiquement pour ce projet (ce qui est généralement le cas, cela pourrait un jour se transformer en un extrait de code "statique" utilisé dans de nombreux projets ou un sous-module git, etc. auquel cas il devrait certainement se trouver dans le dossier lib) alors peut-être que sa place ne se trouve pas du tout dans le dossier lib. Peut-être que cela devrait être dans un sous-dossier sous le dossier de l'application · J'ai le sentiment que c'est la nouvelle façon de faire les rails. De toute évidence, la même magie opère partout dans les chemins de chargement automatique dans lesquels vous mettez vos trucs, donc c'est bon pour ces choses. Quoi qu'il en soit, ce ne sont que mes réflexions sur le sujet. Vous êtes libre d'être en désaccord. :)
MISE À JOUR: À propos du type de magie ..
Comme l'a souligné Severin dans son commentaire, le noyau "mécanisme de chargement automatique d'un module" fait bien sûr partie de Ruby, mais les trucs de chemins de chargement automatique ne le sont pas. Vous n'avez pas besoin de Rails pour faire
autoload :Foo, File.join(Rails.root, "lib", "my_stuff", "bar")
. Et lorsque vous essayez de référencer le module Foo pour la première fois, il est chargé pour vous. Cependant, ce que fait Rails, c'est qu'il nous donne un moyen d'essayer de charger automatiquement des choses à partir de dossiers enregistrés et cela a été implémenté de telle sorte qu'il doit supposer quelque chose sur les conventions de dénomination. S'il n'avait pas été implémenté de cette façon, chaque fois que vous faites référence à quelque chose qui n'est pas actuellement chargé, il devra parcourir tous les fichiers de tous les dossiers de chargement automatique et vérifier si l'un d'eux contient ce que vous essayez de référencer. À son tour, cela irait à l'encontre de l'idée du chargement automatique et du chargement automatique. Cependant, avec ces conventions en place, il peut déduire du module / classe que vous essayez de charger où cela pourrait être défini et de le charger.la source
Attention: si vous voulez charger le 'patch singe' ou la 'classe ouverte' depuis votre dossier 'lib', n'utilisez pas l' approche 'autoload' !!!
Approche " config.autoload_paths ": ne fonctionne que si vous chargez une classe définie uniquement en UN endroit. Si une classe a déjà été définie ailleurs, vous ne pouvez pas la charger à nouveau par cette approche.
Approche " config / initializer / load_rb_file.rb ": fonctionne toujours! quelle que soit la classe cible est une nouvelle classe ou une "classe ouverte" ou "patch singe" pour la classe existante, cela fonctionne toujours!
Pour plus de détails, voir: https://stackoverflow.com/a/6797707/445908
la source
Très similaire, mais je pense que c'est un peu plus élégant:
la source
Dans mon cas, j'essayais simplement de charger un fichier directement sous le répertoire lib.
Dans application.rb ...
ne fonctionnait pas, même dans la console, puis quand j'ai essayé
et rails charge parfaitement le fichier.
Je suis toujours assez noble et je ne sais pas pourquoi cela fonctionne, mais cela fonctionne. Si quelqu'un veut m'expliquer, j'apprécierais: DI j'espère que cela aide quelqu'un de toute façon.
la source
J'ai eu le même problème. Voici comment je l'ai résolu. La solution charge le répertoire lib et tous les sous-répertoires (pas seulement le direct). Bien sûr, vous pouvez l'utiliser pour tous les répertoires.
la source
Expected lib/bar/foo.rb to define constant Foo
si vous essayez de charger lib / foo.rb en vous référant à Foo constant.config.autoload_paths ne fonctionne pas pour moi. Je le résous autrement
la source
Si seuls certains fichiers ont besoin d'accéder aux modules dans lib, ajoutez simplement une instruction require aux fichiers qui en ont besoin. Par exemple, si un modèle doit accéder à un module, ajoutez:
en haut du fichier model.rb.
la source
require
dans une application rails, car cela empêcheActiveSupport::Dependencies
de [dé] charger correctement ce code. Au lieu de cela, vous devez utiliserconfig.autoload_paths
comme la réponse ci-dessus, puis inclure / étendre au besoin.require
de n'importe où dans une application Rails? Dans une tâche de râteau Je suis actuellementrequire
-ment etinclude
-ment un module qui vitlib/
. Ne devrais-je pas faire ça?require
votrelib/
code (par exemple ce billet de blog , cette réponse SO ). Je ne sais toujours pas tout. Pouvez-vous donner plus de preuves derrière la réclamation pour non-utilisationrequire
?Épelez le nom de fichier correctement.
Sérieusement. J'ai lutté avec une classe pendant une heure car la classe était Governance :: ArchitectureBoard et le fichier était dans lib / gouvernance / architecture_baord.rb (transposé O et A dans "board")
Cela semble évident rétrospectivement, mais c'est le diable qui l'a suivi. Si la classe n'est pas définie dans le fichier dans lequel Rails s'attend à ce qu'elle soit basée sur la fusion du nom de classe, elle ne le trouvera tout simplement pas.
la source
À partir de
Rails 5
, il est recommandé de mettre le dossier lib sous le répertoire de l' application ou au lieu de créer d' autres espaces de noms significatifs pour le dossier queservices
,presenters
,features
etc et le mettre sous le répertoire d'applications pour le chargement automatique par des rails.Veuillez également consulter ce lien de discussion GitHub .
la source
Il y a plusieurs raisons pour lesquelles vous pourriez avoir des problèmes de chargement à partir de lib - voir ici pour plus de détails - http://www.williambharding.com/blog/technology/rails-3-autoload-modules-and-classes-in-production/
la source