Observers Big and Small 6
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.
Enjoying the content? Be sure to subscribe to my RSS feed.





This is great to know. I’ve used observers before, mostly in the context of caching views, but not for observing events in models. It seems to me that if you have more than one
before_[whatever]orafter_[whatever]in your model it’s probably best to move them into an observer. I have a few models that have a ton of these callbacks that will be nice to move out into another location. Thanks!Why not just use ActiveRecord callback hooks instead of Observers? Are Observers more powerful or is it just a matter of preference?
Yeah, I’d like to know the benefits too. Can you shed some light on this Robby?
(I’d also like the ability to use the logger from within an observer, but that’s another issue)
Eric A
2 rules of thumb:Otherwise use/consider observers.
Creating a new record may be cause for some action to be triggered. If that action is tangential to the model which triggers it then it makes sense to keep that action separate. The AR docs have some logical examples that should help you see the point of using observers.
Observers use the same AR callbacks. You don’t use observers as a replacement for AR callbacks; observers augment the usefulness of the AR callbacks.
Thanks for the comments!
I’ve posted a follow up to this article with responses to some of our questions.