2010-10-12 11 views
5

Ich habe rund 40 Modelle in meiner RoR-Anwendung. Ich möchte einen After_Save-Callback für alle Modelle einrichten. Eine Möglichkeit besteht darin, sie allen Modellen hinzuzufügen. Da dieser Callback denselben Code zum Ausführen hat, gibt es eine Möglichkeit, ihn einmal global zu definieren, sodass er für alle Modelle aufgerufen wird.ActiveRecord Globale Rückrufe für alle Modelle

Ich habe versucht, dies ohne Glück:

class ActiveRecord::Base 

    after_save :do_something 

    def do_something 
    # .... 
    end 
end 

gleiche Code funktioniert, wenn ich es in einzelnen Modellen zu tun.

Danke, Imran

Antwort

8

Sie sollen Beobachter für diesen Einsatz:

class AuditObserver < ActiveRecord::Observer  

    observe ActiveRecord::Base.send(:subclasses) 

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

Um einen Beobachter zu aktivieren, ist es in der config.active_record.observers Konfigurationseinstellung in Ihrer config/Anwendungsliste. RB-Datei.

config.active_record.observers = :audit_observer 

Hinweis

In Rails 4 wird die Beobachter-Funktion von Kern entfernt. Verwende das https://github.com/rails/rails-observers Juwel.

+0

Großartig, danke! also muss ich alle Modelle hinzufügen "beobachten", oder? Ich hoffe, es wäre eine Möglichkeit, die Liste der Modelle dynamisch abzurufen und an "beobachten" zu übergeben? Danke nochmal. – Saim

+0

Ich habe gerade folgendes gefunden: http://stackoverflow.com/questions/516579/is-there-a-way-to-get-a-collection-of-all-the-model-in-your-rails- app – Saim

+0

Meine Antwort aktualisiert, werfen Sie einen Blick. –

3

Ich bin ziemlich spät dran, aber für den Fall, dass jemand anderes Rails 3 benutzt und das findet, könnte diese Antwort helfen.

Einige Modelle werden möglicherweise nicht geladen, wenn der Beobachter geladen wird. Die Dokumentation besagt, dass Sie observed_classes überschreiben können, und auf diese Weise können Sie die Unterklassen des aktiven Datensatzes dynamisch abrufen.

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

Das ist wirklich cool, aber ich würde ermutigen, 'ActiveRecord :: Base.descendants' zu verwenden, um den Aufruf der privaten Methode zu vermeiden. – ludwigschubert

0

Das funktioniert eigentlich ziemlich gut für mich in 2.3.8:

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

Dies schien für mich zu arbeiten:

ActiveRecord::Base.after_save do 
    ... 
end 

Gibt es ein Problem, das ich bin nicht zu sehen?

Verwandte Themen