Alex Rivera | Logout

Rails Observers - When to and when not to use observers in Rails

Asked 2011-02-01T18:34:13.333
12

In an application that I'm working currently, I see lots of observers. This is indeed creating lot trouble for me while I make code changes, add new functionality, as these observers cause tons of side-effects.

I would like to know the occasions that demand an Observer and the ones people have experiences either empirical or personal on when one gets tempted to fall in the observer trap.

Your valuable experience, war-stories and thoughts are in demand. Please do shout out!

Edit
Report

1 Answer

35

I feel that observers get a bad rap largely because people lump them in with ActiveRecord lifecycle callbacks as being the same thing. I do agree with a lot of the popular opinion on lifecycle callbacks being easy to misuse, getting yourself in a tangle, but I'm personally a big fan of observers for keeping things out of model classes that are not the particular model's core responsibility. Here's a hint: Rails' observers were partly inspired by aspect-oriented programming -- they're about cross-cutting concerns. If you're putting business logic in observers that is tightly coupled to the models they're observing, you're doing it wrong IMO.

They're ideal for keeping clutter out of model classes, like cache expiration (sweepers), notifications of various sorts, activity stream updates, kicking off background jobs to track custom analytics events, warm caches, etc.

I emphatically disagree with BlueFish about observers being difficult to properly unit test. This is precisely the biggest point that distinguishes them from lifecycle callbacks: you can test observers in isolation, and doing so discourages you from falling into many of the state- and order-heavy design pitfalls BlueFish refers to (which again I think is more often true of lifecycle callbacks).

Here's my prescription:

  1. Disable all observers in your test suite by default. They should not be complicating your model tests because they should have separate concerns anyway. You don't need to unit test that observers actually fire, because ActiveRecord's test suite does that, and your integration tests will cover it. Use the block form of ActiveRecord::Base.observers.enable if you really believe there is a good reason to enable an observer for some small piece of your unit tests, but it's likely an indicator of misuse or a design problem.
  2. Enable observers for your integration tests only. Integration tests of c
answered 2013-02-20T06:09:41.533

Your Answer