0

J'ai un petit bijou:Comment puis-je faire en sorte que Rails cesse de recharger mes gemmes?

# in /Library/Ruby/Gems/1.8/gems/my_gem-1.0.0/lib/my_gem.rb 
module MyGem 
    def do_stuff 
    .. 
    end 
end 

Et je l'ai chargé dans Rails:

# in [rails_root]/config/environment.rb: 
config.gem 'my_gem', :version => '1.0.0' 

Et utilisé:

# in [rails_root]/app/controllers/application_controller.rb 
class ApplicationController < ActionController::Base 
    include MyGem 
end 

Mais je dois singe-patch un peu en un moyen spécifique à l'environnement:

# in [rails_root]/config/environments/development.rb: 
MyGem.class_eval do 
    def do_stuff 
    raise 'Ack! - just testing' 
    end 
end 

Malheureusement, MyGem recharge à chaque requête, donc mon patch de singe est inutile.

J'ai vérifié load_once_paths:

ActiveSupport::Dependencies.load_once_paths 
# => ["/Library/Ruby/Gems/1.8/gems/my_gem-1.0.0/lib", "other stuff"] 

Toute idée comment je peux obtenir l'effet que je veux?

Répondre

3

Semble que vous travaillez en mode développement où Rails charge toutes les classes dans chaque requête pour aider le développeur à refléter les changements de code + vous avez inclus la gemme dans votre contrôleur. Pour remédier à ce rendez-vous à project_path/config/environnements/development.rb et ajoutez cette ligne

config.cache_classes = true 

Notez que vous n'aurez pas vos modifications de code reflète à moins que vous redémarrez le serveur.

Mise à jour 1: En tant que deuxième solution, vous pouvez également ajouter le correctif moneky après avoir inclus la gemme dans ce contrôleur. Vous pouvez l'ajouter au bas de votre fichier de contrôleur.

Mise à jour 2: Une troisième solution (recommandé) Si vous pouvez ajouter l'extrait suivant à my_gem.rb

class ActionController::Base 
    include MyGem 
end 

alors les choses devraient fonctionner comme vous ne aurez pas besoin d'inclure manuellement dans votre contrôleur d'application.

0

Si vous incluez la gemme dans votre environment.rb, vous ne devriez pas avoir besoin de l'inclure dans votre contrôleur. Vous voudrez peut-être réfléchir à la façon dont la gemme se connecte à ActionController. Il semble que vous souhaitiez ajouter des méthodes de classe à ActionController :: Base, ce qui est assez simple. Jetez un oeil à combien de gemmes communes implémenter cela.

Il semble aussi, comme vous pourriez même vouloir vérifier l'existence & valeur de RAILS_ENV pour assurer un comportement différent pour les différents environnements.

+0

Je suis _requiring_ it (implicitement) dans environment.rb; Je suis _including_ dans ApplicationController. Ce sont des actions très différentes. Ce que je me demande, c'est pourquoi Rails recharge la gemme chaque fois qu'il recharge ApplicationController. La preuve qu'il le fait est que mon patch de singe disparaît. –

Questions connexes