2010-10-12 24 views
5

Ho circa 40 modelli nella mia applicazione RoR. Voglio impostare un callback after_save per tutti i modelli. Un modo è aggiungerlo a tutti i modelli. Poiché questo callback ha lo stesso codice da eseguire, esiste un modo per definirlo globalmente una volta in modo che venga richiamato per tutti i modelli.Callback globali ActiveRecord per tutti i modelli

ho provato questo senza fortuna:

class ActiveRecord::Base 

    after_save :do_something 

    def do_something 
    # .... 
    end 
end 

stesso codice funziona se lo faccio in singoli modelli.

Grazie, Imran

risposta

8

Si dovrebbero usare gli osservatori per questo:

class AuditObserver < ActiveRecord::Observer  

    observe ActiveRecord::Base.send(:subclasses) 

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

Per attivare un osservatore, elencare nella impostazione di configurazione config.active_record.observers nella configurazione/applicazione. file rb.

config.active_record.observers = :audit_observer 

Nota

In rotaie 4, la funzione di osservatore viene rimosso dal nucleo. Utilizza la gemma https://github.com/rails/rails-observers.

+0

Grande, grazie! quindi ho bisogno di aggiungere tutti i modelli per "osservare", giusto? Spero ci sia modo di recuperare in modo dinamico la lista dei Modelli e passarla a "osservare"? Grazie ancora. – Saim

+0

Ho appena trovato questo: http://stackoverflow.com/questions/516579/è-questo-una-pagina-una-collection-di-modelli-in-modelli-in-il-vostro- app – Saim

+0

Aggiornato la mia risposta, dai un'occhiata. –

3

Sono piuttosto in ritardo su questo, ma nel caso in cui qualcun altro stia utilizzando Rails 3 e trova questo, allora questa risposta potrebbe aiutare.

Alcuni modelli potrebbero non essere caricati quando l'osservatore è caricato. La documentazione dice che è possibile sovrascrivere observ_classes e in questo modo è possibile ottenere dinamicamente le sottoclassi del record attivo.

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

Questo è davvero interessante, ma vorrei incoraggiare l'uso di 'ActiveRecord :: Base.descendants' per evitare la chiamata al metodo privato. – ludwigschubert

0

Questo in realtà funziona abbastanza bene per me in 2.3.8:

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

Questo sembrava funzionare per me:

ActiveRecord::Base.after_save do 
    ... 
end 

C'è un problema che non sto vedendo?

Problemi correlati