2010-10-12 13 views
5

Tengo alrededor de 40 modelos en mi aplicación RoR. Quiero configurar una devolución de llamada after_save para todos los modelos. Una forma es agregarlo a todos los modelos. Dado que esta devolución de llamada tiene el mismo código para ejecutar, ¿hay alguna manera de definirlo globalmente una vez para que se invoque para todos los modelos?Callbacks globales de ActiveRecord para todos los modelos

yo probamos este sin suerte:

class ActiveRecord::Base 

    after_save :do_something 

    def do_something 
    # .... 
    end 
end 

mismo código funciona si lo hago en modelos individuales.

Gracias, Imran

Respuesta

8

Se deben usar los observadores para esto:

class AuditObserver < ActiveRecord::Observer  

    observe ActiveRecord::Base.send(:subclasses) 

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

el fin de activar un observador, incluirla en el valor de configuración config.active_record.observers en tu config/aplicación. archivo rb

config.active_record.observers = :audit_observer 

Nota

En los carriles 4, la función de observador se retira del núcleo. Use la gema https://github.com/rails/rails-observers.

+0

Muy bien, gracias! así que necesito agregar todos los modelos para "observar", ¿verdad? Espero que haya alguna forma de obtener dinámicamente la lista de modelos y pasarla a "observar"? Gracias de nuevo. – Saim

+0

Acabo de encontrar esto: http://stackoverflow.com/questions/516579/is-there-a-way-to-get-a-collection-of-all-the-models-in-your-rails- aplicación – Saim

+0

Actualizado mi respuesta, eche un vistazo. –

3

Llego bastante tarde en este caso, pero en caso de que alguien más esté utilizando Rails 3 y lo encuentre, esta respuesta podría ayudar.

Es posible que algunos modelos no se carguen cuando se carga el observador. La documentación dice que puede anular las clases observadas, y de esa manera puede obtener las subclases del registro activo de forma dinámica.

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

Esto es realmente genial, pero recomendaría usar 'ActiveRecord :: Base.descendants' para evitar la llamada al método privado. – ludwigschubert

0

En realidad, esto funciona bastante bien para mí en 2.3.8:

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

Esto parecía funcionar para mí:

ActiveRecord::Base.after_save do 
    ... 
end 

¿Hay un problema que no estoy viendo?

Cuestiones relacionadas