276 votes

La meilleure façon de charger le module/classe de dossier lib dans Rails 3?

Depuis la dernière Rails 3, la libération n'est pas auto-chargement des modules et des classes de lib plus, quelle serait la meilleure façon de les charger?

À partir 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);

252voto

Slobodan Kovacevic Points 4622

Comme des Rails 2.3.9, il y a un paramètre en config/application.rb dans laquelle vous pouvez spécifier les répertoires contenant les fichiers que vous souhaitez chargées automatiquement.

À partir de l'application.rb:

# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/extras)

200voto

thankful Points 1687
# Autoload lib/ folder including all subdirectories
config.autoload_paths += Dir["#{config.root}/lib/**/"]

Source: Rails 3 Quicktip: Autoload répertoire lib, y compris tous les sous-répertoires, éviter le chargement paresseux

Veuillez garder à l'esprit que les fichiers contenus dans le dossier lib ne sont chargés que lorsque le serveur est démarré. Si vous voulez le confort de autoreload ces fichiers, lire: Rails 3 Quicktip: le rechargement Automatique de lib, le mode de développement. Sachez que ce n'est pas fait pour un environnement de production depuis la permanente de rechargement ralentit la machine.

84voto

Timo Lehto Points 1603

La magie de l'auto-chargement des trucs

Je pense que l'option de contrôle de la dossiers à partir de laquelle le chargement automatique genre de choses se fait a été suffisamment traités dans d'autres réponses. Toutefois, au cas où quelqu'un d'autre est d'avoir de la difficulté des trucs chargé mais ils ont eu leur chargement automatique de chemins modifiée en tant que de besoin, alors cette réponse tente d'expliquer ce qu'est la magie de ce autoload chose.

Alors, quand il s'agit de chargement des trucs de sous-répertoires, il y a un piège ou d'une convention, vous devez être conscient. Parfois, le Ruby/Rails de la magie (cette fois-ci essentiellement Rails), peut rendre difficile de comprendre pourquoi quelque chose se passe. Tout module déclaré dans l'autoload chemins sont chargés uniquement si le nom du module correspond au nom du répertoire parent. Ainsi, dans le cas où vous essayez de mettre en lib/my_stuff/bar.rb quelque chose comme:

module Foo
  class Bar
  end
end

Il ne sera pas chargé automatiquement. Puis, de nouveau, si vous renommez le parent dir d' foo ainsi l'hébergement de votre module au chemin d'accès: lib/foo/bar.rb. Il sera là pour vous. Une autre option est de donner un nom au fichier que vous souhaitez chargés automatiquement par le nom du module. Évidemment, il ne peut être un fichier de ce nom alors. Dans le cas où vous avez besoin de partager vos trucs dans de nombreux fichiers, vous pouvez bien sûr utiliser un fichier d'exiger d'autres fichiers, mais je ne le recommande pas, car alors quand sur le mode de développement et de modifier les autres fichiers puis de les Rails est pas en mesure de recharger automatiquement pour vous. Mais si vous voulez vraiment vous pourriez avoir un fichier par le nom du module qui précise ensuite que les fichiers nécessaires à l'utilisation du module. Vous pouvez donc avoir deux fichiers: lib/my_stuff/bar.rb et lib/my_stuff/foo.rb et le premier étant le même que ci-dessus et le second contenant une seule ligne: require "bar" et qui fonctionne de la même façon.

P. S. je me sens obligé d'ajouter une chose plus importante. Comme ces derniers temps, chaque fois que je veux avoir quelque chose dans le répertoire lib qui ont besoin d'être chargées automatiquement, j'ai tendance à commencer à penser que si c'est quelque chose que je suis en train de développer spécifiquement pour ce projet (généralement c'est le cas, il pourrait un jour se transformer en "statique" extrait de code utilisé dans de nombreux projets ou un git sous-module, etc.. dans ce cas il devrait certainement être dans le dossier lib), alors peut-être que sa place n'est pas dans le dossier lib du tout. Il devrait peut-être être dans un sous-dossier dans le dossier app· j'ai le sentiment que c'est le nouveau rails façon de faire les choses. De toute évidence, la même magie est à l'œuvre partout où dans vous de chargement automatique de chemins de mettre vos affaires en tant qu'il est bon de ces choses. De toute façon, c'est juste mes pensées sur le sujet. Vous êtes libre d'être en désaccord. :)


Mise à JOUR: Sur le type de magie..

Comme severin a souligné dans son commentaire, le coeur de "l'auto-chargement d'un module mécanisme" est sûr, c'est une partie de Ruby, mais le chargement automatique de chemins de choses n'est pas. Vous n'avez pas besoin de Rails à ne autoload :Foo, File.join(Rails.root, "lib", "my_stuff", "bar"). Et quand vous essayez de référence le module Foo pour la première fois, alors il serait chargé pour vous. Cependant, ce que les Rails ne s'agit-il nous donne un moyen d'essayer de charger des trucs magiquement de l'enregistrement des dossiers, ce qui a été mis en œuvre de telle manière qu'il doit assumer quelque chose sur les conventions de nommage. Si elle n'avait pas été mis en œuvre comme cela, alors à chaque fois que vous faites référence à quelque chose qui n'est actuellement pas chargé, il faudrait aller à travers tous les fichiers de tous le chargement automatique des dossiers et vérifier si l'un d'entre eux contient ce que vous essayiez de référence. Ce à son tour, à l'encontre de l'idée d'auto-chargement et autoreloading. Cependant, avec ces conventions, il peut déduire à partir du module/de la classe de votre tentative de chargement d'où cela pourrait être défini et il suffit de charger.

J'espère que j'ai bien compris cette fois? :)

41voto

Siwei Shen Points 5814

Attention: si vous voulez charger le "monkey patch" ou "classe ouverte" de votre 'lib' dossier, de ne pas utiliser le 'autoload' approche!!!

  • "config.autoload_paths" approche: ne fonctionne que si vous êtes le chargement d'une classe définie uniquement dans "UN". Si une classe a déjà été défini quelque part d'autre, alors vous ne pouvez pas charger à nouveau par cette approche.

  • "config/initializer/load_rb_file.rb": marche toujours! quelle que soit la classe cible est une nouvelle classe ou une "classe ouverte" ou "monkey patch" pour la classe existante, il fonctionne toujours!

Pour plus de détails , voir: http://stackoverflow.com/a/6797707/445908

28voto

Brian Armstrong Points 8259

Très similaire, mais je pense que c'est un peu plus élégant:

config.autoload_paths += Dir["#{config.root}/lib", "#{config.root}/lib/**/"]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X