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!
end
end
# controller(s)
class FlowerController < ApplicationController
observer :flower_observer
end
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.