Filters and Observers in Rails

July 2, 2008

Though I’m a little late to the Rails party. If you have yet to experience the goodness of these this is the place where you need to peep into.

Observers in Rails:

This is a great way to reduce the clutter that normally comes when the model class is burdened with functionality that doesn‘t pertain to the core responsibility of the class. Observer classes respond to lifecycle callbacks to implement trigger-like behavior outside the original class.

In my project I had a requirement to perform some action after creating every actor. Instead loading the model we decided to move it to the observers.

A better example where to use observers would be. Consider in a forum kind of application, If any new comment is added to the topic all the people in the group has to be sent a notification-mail about the comment.

Instead having the sending mail part in the model we can have it in a observer so that it’ll get triggered after every save action.

class CommentObserver < ActiveRecord::Observer
    def after_save(comment)
      Notifications.deliver_comment("admin@do.com", "New comment was posted", comment)
    end
end

This Observer sends an email when a Comment#save is finished.

Observers will by default be mapped to the class with which they share a name.If you want to name your observer differently than the class you‘re interested in observing, you can use the Observer.observe class method which takes either the concrete class (Product) or a symbol for that class (:product)

class AuditObserver < ActiveRecord::Observer
    observe :account, :balance
    def after_update(record)
      AuditTrail.new(record, "UPDATED")
    end
  end

The AuditObserver will now act on both updates to Account and Balance by treating them both as records.

Storing Observers in Rails
If you‘re using Active Record within Rails, observer classes are usually stored in app/models with the naming convention of app/models/audit_observer.rb.

Configuration

In order to activate an observer, list it in the config.active_record.observers configuration setting in your config/environment.rb file.

  config.active_record.observers = :comment_observer, :signup_observer

Observers will not be invoked unless you define these in your application configuration.

Some call backs available in rails are

  • save
  • valid
  • before_validation
  • before_validation_on_create
  • validate
  • validate_on_create
  • after_validation
  • after_validation_on_create
  • before_save
  • before_create
  • create
  • after_create
  • after_save

Enjoy the magic of Rails using these observers…….

We’ll see how to use filters in rest of the post.

Filters in Rails:

Filters enable controllers to run shared pre- and post-processing code for its actions. These filters can be used to do authentication, caching, or auditing before the intended action is performed. Or to do localization or output compression after the action has been performed. Filters have access to the request, response, and all the instance variables set by other filters in the chain or by the action (in the case of after filters).

Controller inheritance hierarchies share filters downwards, but subclasses can also add or skip filters without affecting the superclass. For example:

class BankController < ActionController::Base
    before_filter :login_required,:audit
    private
      def login_required
        # Check user authentication
      end
      def audit
        # record the action and parameters in an audit log
      end
end
class VaultController < BankController
    before_filter :verify_credentials
    private
      def verify_credentials
        # make sure the user is allowed into the vault
      end
end

Few calls back methods available with rails are

  • after_filter
  • append_after_filter
  • append_around_filter
  • append_before_filter
  • around_filter
  • before_filter
  • filter_chain
  • prepend_after_filter
  • prepend_around_filter
  • prepend_before_filter
  • skip_after_filter
  • skip_before_filter
  • skip_filter

Skipping a filter

How to skip a filter?

before_filter :login_required, :except => :create
before_filter :login_required, :only => :show

Or using methods like
Skip_before_filter :login_required

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: