2010-10-12 5 views
5

J'ai environ 40 modèles dans mon application RoR. Je veux configurer un rappel after_save pour tous les modèles. Une façon est de l'ajouter à tous les modèles. Puisque ce rappel a le même code à exécuter, est-il possible de le définir globalement une fois pour qu'il soit invoqué pour tous les modèles.ActiveRecord Global Callbacks pour tous les modèles

J'ai essayé sans succès:

class ActiveRecord::Base 

    after_save :do_something 

    def do_something 
    # .... 
    end 
end 

Même code fonctionne si je le fais dans les modèles individuels.

Merci, Imran

Répondre

8

Vous devez utiliser des observateurs pour cela:

class AuditObserver < ActiveRecord::Observer  

    observe ActiveRecord::Base.send(:subclasses) 

    def after_save(record) 
    AuditTrail.new(record, "UPDATED") 
    end 
end 

Pour activer un observateur, la liste dans le paramètre de configuration config.active_record.observers dans votre config/application. fichier rb.

config.active_record.observers = :audit_observer 

Remarque

Dans Rails 4, la fonction d'observateur est retiré du noyau. Utilisez la gemme https://github.com/rails/rails-observers.

+0

Grand, merci! donc j'ai besoin d'ajouter tous les modèles pour "observer", non? J'espère qu'il y aurait moyen de récupérer dynamiquement la liste des modèles et de la transmettre pour "observer"? Merci encore. – Saim

+0

Je viens de trouver ceci: http://stackoverflow.com/questions/516579/-there-a-way-to-get-a-collection-of-all-the-models-in-your-rails- application – Saim

+0

Mis à jour ma réponse, jetez un coup d'oeil. –

3

Je suis assez en retard sur celui-ci, mais dans le cas où quelqu'un d'autre utilise Rails 3 et trouve cela, alors cette réponse pourrait aider.

Certains modèles peuvent ne pas être chargés lorsque l'observateur est chargé. La documentation dit que vous pouvez surcharger observé_classes, et ainsi vous pouvez obtenir dynamiquement les sous-classes de l'enregistrement actif.

class AuditObserver < ActiveRecord::Observer 
    def self.observed_classes     
    ActiveRecord::Base.send(:subclasses)  
    end 
end 
+0

C'est vraiment cool, mais je vous encourage à utiliser 'ActiveRecord :: Base.descendants' pour éviter l'appel de la méthode privée. – ludwigschubert

0

Cela fonctionne en fait assez bien pour moi en 2.3.8:

class AudiObserver < ActiveRecord::Observer 
    observe :'ActiveRecord::Base' 
    # 
    # observe methods... 
    # 
end 
1

Cela semblait fonctionner pour moi:

ActiveRecord::Base.after_save do 
    ... 
end 

Y at-il un problème que je ne vois pas?

Questions connexes