Read my latest article: 8 things I look for in a Ruby on Rails app (posted Thu, 06 Jul 2017 17:59:00 GMT)

Observers Big and Small

Posted by Fri, 27 Apr 2007 18:15:00 GMT

1 comment Latest by Gordon Yeong Tue, 19 Jan 2010 22:43:46 GMT

My colleague, Gary, keeps a stack of Ruby and Rails books on his desk and was implementing an Observer into a client project. It appears that the Agile Web Development with Rails book is still encouraging people to do the following in order to load an Observer.

# app/models/flower_observer.rb
class FlowerObserver < ActiveRecord::Observer
  observe Flower

  def after_create(model)
    # model.do_something!

# controller(s)
class FlowerController < ApplicationController
  observer :flower_observer

What is wrong with this approach?

Well, in order for your Observer to be used, the model(s) callbacks that it is observing need to be triggered through a controller. If you end up writing any scheduled rake tasks, your observer will not be called. In my opinion, the controller shouldn’t know this much about the model. In fact, the model doesn’t even really know about it’s observer… so why should a controller?

This was actually changed a long time ago (I previously blogged about a different solution here) and the Rails docs for ActiveRecord::Observer are currently correct.

Observers in the Environment

If you open up a recent version of config/environment.rb, you notice in the comments the following.

  # Activate observers that should always be running
  # config.active_record.observers = :cacher, :garbage_collector

Take a moment to go ahead and specify which observer(s) you’d like to load into your Rails environment.

config.active_record.observers = :flower_observer

Then you can remove your observer calls in all your controllers, because that’s not where you should be defining them.

Also, if you’re not using Observers yet, I’d really encourage you to consider reading up on them and giving them a try.