Observational: Better Observers for ActiveRecord
This sort of thing appears in just about every rails app I've ever worked on:
class User after_create :send_welcome_email protected def send_welcome_email Notifier.deliver_welcome_email(self) end end
Why would the user have to ask the notifier to send him his own welcome message? That seems like the Notifier's responsibility, if you ask me.
Using an ActiveRecord observer, we can absolve the user of that responsibility. That code would look something like this:
class UserObserver < ActiveRecord::Observer def after_create(user) Notifier.deliver_welcome_email(user) end end
Note that you'd also have to activate this observer in config/environment.rb.
In some ways, using an observer is better than putting a callback in the User model. It's definitely a better division of responsibilities. But, it feels a little cumbersome.
In the rails app where I spend most of my time, we currently use callbacks to trigger over a dozen mailers, and almost 50 types of activity feed items. So, we'd need a lot of observer subclasses.
A Better Way
The observer pattern, in some form, seemed like the right approach. I wanted to find a way to use it without creating eleventy billion observer classes.
I came up with a gem that I call observational. Here's what it looks like:
class Notifier < ActionMailer::Base observes :user, :after => :create, :invokes => :deliver_welcome_email def welcome_email(user) end end
This example is functionally equivalent to the first example above. Notifier.deliver_welcome_email will be called during the after_create callback of any User object, with the user object as the first and only argument.
Observational supports any standard ActiveRecord callback. As far as I know, anything you can do with a standard AR observer, you can do with observational. Let me know if I'm wrong about that.
Get It!
sudo gem install giraffesoft-observational
Fork it at github.
Or read the yardoc at rdoc.info.