views:

25

answers:

1

Hi All,

I have around 40 models in my RoR application. I want to setup a after_save callback for all models. One way is to add it to all models. Since this callback has the same code to run, is there a way to define it globally once so that it gets invoked for all models.

I tried this with no luck:

class ActiveRecord::Base

  after_save :do_something

  def do_something
    # .... 
  end
end

Same code works if I do it in individual models.

Thanks, Imran

+2  A: 

You should use observers for this:

class AuditObserver < ActiveRecord::Observer      

  observe ActiveRecord::Base.send(:subclasses)

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

In order to activate an observer, list it in the config.active_record.observers configuration setting in your config/application.rb file.

config.active_record.observers = :audit_observer
KandadaBoggu
Great, thanks! so I need to add all the models to "observe", right?I hope there would be way to dynamically fetch the list of Models and pass it to "observe"?Thanks again.
Imran
I just found this:http://stackoverflow.com/questions/516579/is-there-a-way-to-get-a-collection-of-all-the-models-in-your-rails-app
Imran
Updated my answer, take a look.
KandadaBoggu
That's cool. I think we need to add this line before the "observe" to make sure all models are loaded:Dir.glob(RAILS_ROOT + '/app/models/*.rb').each { |file| require file }Please correct me if I am wrong, or if there is a better to make sure all models are loaded.
Imran
If all your models are in the `models` directory this should work. Try it out and see. Should be pretty straight forward. Simply print the result of ` ActiveRecord::Base.send(:subclasses)` inside the `AuditObserver` class.
KandadaBoggu