Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActiveRecord Global Callbacks for all Models

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

like image 766
Saim Avatar asked Oct 12 '10 10:10

Saim


People also ask

What are model callbacks in rails?

Callbacks are methods that get called at certain moments of an object's life cycle. With callbacks it is possible to write code that will run whenever an Active Record object is created, saved, updated, deleted, validated, or loaded from the database.

What are Active Record callbacks?

Active Record Callbacks are hooks to which we can register methods in our models. These hooks are executed in various stages of an Active Record object lifecycle. The following callbacks are run when an object is created. These callbacks are executed in the order in which they are listed below.

What is Active Record in Ruby on Rails?

Active Record is the M in MVC - the model - which is the layer of the system responsible for representing business data and logic. Active Record facilitates the creation and use of business objects whose data requires persistent storage to a database.

What is the difference between delete and destroy in rails?

Basically destroy runs any callbacks on the model while delete doesn't. Deletes the record in the database and freezes this instance to reflect that no changes should be made (since they can't be persisted). Returns the frozen instance.


2 Answers

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

Note

In Rails 4, the observer feature is removed from core. Use the https://github.com/rails/rails-observers gem.

like image 129
Harish Shetty Avatar answered Oct 07 '22 03:10

Harish Shetty


I'm pretty late on this one, but in case someone else is using Rails 3 and finds this, then this response might help.

Some models might not be loaded when the observer is loaded. The documentation says that you can override observed_classes, and that way you can get the subclasses of active record dynamically.

class AuditObserver < ActiveRecord::Observer
  def self.observed_classes                 
    ActiveRecord::Base.send(:subclasses)    
  end
end
like image 4
aalin Avatar answered Oct 07 '22 02:10

aalin