73 votes

L'ajout de lib à 'config.autoload_paths' dans Rails 3 ne permet pas de charger automatiquement mon module.

Je place un fichier nommé g.rb dans le côté Rails.root/lib dossier Le contenu du fichier est le suivant :

module Google
end

Puis j'ajoute

config.autoload_paths += %W(#{config.root}/lib #{Rails.root}/app/delayed_jobs)

à mon Rails.root/config/application.rb

Cependant, lorsque j'essaie d'invoquer Google à partir de rails console une exception est levée. L'exception disparaît seulement si j'exécute require 'google' . Pourquoi ? Mon fichier ne devrait-il pas être chargé automatiquement et ne devrais-je pas accéder au module sans avoir à payer de frais supplémentaires ? require déclaration ?

113voto

Phương Nguyễn Points 2976

Hmm, j'ai découvert une chose intéressante. Pour que Rails charge automatiquement ma classe, le nom de la classe doit être conforme au nom du fichier et à la structure du dossier. Par exemple, si je veux que le module Google soit chargé automatiquement, je dois le placer à l'intérieur de google.rb directement sous /lib (au cas où je spécifierais un chargement automatique à partir de /lib). Si je veux charger automatiquement Google::Docs puis je le place soit à l'intérieur google.rb ou google/docs.rb

27voto

Don Points 1414

J'ai eu un problème similaire pour faire fonctionner mon module sur Heroku. En plus de la convention de nommage autoload indiquée par Stephen C, j'ai découvert que le code du module doit être require en raison d'un threadsafe hypothèse faite par l'environnement de production de Rails sur Heroku (même si threadsafe a été commenté dans mon production.rb fichier de configuration). Dès que je require d le fichier du module avant d'appeler include sur le module, tout a commencé à fonctionner.

require 'mymodule'
include Mymodule

Veuillez jeter un coup d'œil à cet excellent article sur le sujet de l'obtention de modules à charger correctement dans Heroku (production).

24voto

Stephen C Points 511

C'est parce que le point de l'autoload est pas d'exiger tout au départ (pénalité de démarrage). Les classes sont chargées lorsqu'elles sont nécessaires/référencées. Pour ce faire, vous avez besoin d'un moyen de savoir où chercher la classe. Sinon, il faudrait charger à l'avance chaque fichier du répertoire autoload pour voir quelles classes sont déclarées. C'est un compromis, mais exiger tout à l'avance (comme le suggère marbaq) n'est pas de l'autoload. Vous pouvez utiliser la commande autoload fournie par Ruby, qui prend deux arguments, le module à charger (symbolisé, c'est-à-dire :Google dans votre cas), et le second argument est le nom du fichier, qui serait g.rb si lib est dans votre chemin de chargement ($ :). Voir la documentation Ruby sur le chargement automatique.

7voto

E. Sambo Points 176

Changement config.autoload_paths a config.eager_load_paths

(sur la base de Problème Rails #6850 y Forcer le rechargement ! du répertoire lib dans la console de rails 3.2 )

1voto

morbaq Points 841

J'ai été confronté au même problème à l'instant, et ma "solution" (ou plutôt mon contournement) a été d'exiger manuellement chaque fichier nécessaire de Rails.Root/lib dans mon application.rb.

require 'lib/message'
require 'lib/store'
require 'lib/vault/vault.rb'
require 'lib/custom_loggers'

module MyApplication
  class Application < Rails::Application

Ma prochaine étape consisterait à classer les fichiers dans des dossiers de modules, comme vous le mentionnez.

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