Observers vs. Callbacks Observers vs. Callbacks ruby-on-rails ruby-on-rails

Observers vs. Callbacks


One really important distinction to keep in mind, which is related to Milan Novota's answer, is that callbacks on an ActiveRecord have the ability to cancel the action being called and all subsequent callbacks, where as observers do not.

class Model < ActiveRecord::Base  before_update :disallow_bob  def disallow_bob  return false if model.name == "bob"  endendclass ModelObserver < ActiveRecord::Observer  def before_update(model)    return false if model.name == "mary"  endendm = Model.create(:name => "whatever")m.update_attributes(:name => "bob")=> false -- name will still be "whatever" in databasem.update_attributes(:name => "mary")=> true -- name will be "mary" in database

Observers may only observe, they may not intervene.


You can use observers as a means of decoupling or distribution of responsibility. In the basic sense - if your model code gets too messy start to think about using observers for some unessential behavior. The real power (at least as I see it) of observers lies in their ability to serve as a connection point between your models and some other subsystem whose functionality is used by all (or some) of the other classes. Let's say you decide to add an IM notification to your application - say you want to be notified about some (or all) of the CRUD actions of some (or all) of the models in your system. In this case using observers would be ideal - your notification subsystem will stay perfectly separated from your business logic and your models won't be cluttered with behavior which is not of their business. Another good use case for observers would be an auditing subsystem.


A callback is more short lived: You pass it into a function to be called once. It's part of the API in that you usually can't call the function without also passing a callback. This concept is tightly coupled with what the function does. Usually, you can only pass a single callback..

Example: Running a thread and giving a callback that is called when the thread terminates.

An observer lives longer and it can be attached/detached at any time. There can be many observers for the same thing and they can have different lifetimes.

Example: Showing values from a model in a UI and updating the model from user input.