We can take your startup from idea to revenue.   Find out more ยป


RoR: Using ActionController Filters

Ruby

As with any project, you start to see patterns and decide to refactor. One common pattern I was seeing was the need to load a model by ID for quite a few of my controller’s actions. Here is the code I wanted to refactor:

    if params["id"]
      begin
        @org = Organization.find(params["id"])
      rescue
        error_page(”Organization not found”) and return
      end
    else
      error_page(”Id is required”) and return
    end

This code calls a handy method on my project’s ApplicationController to display an error message if the id is missing or the organization isn’t found. Rather than pasting this code in each action, I opted to spend about 10 minutes learning how filtering works by visiting the RailsManual.com ActionController::Filters page .

I simply moved this common code into a protected function on my OrganizationController called check_and_load_organization, and return false in the instances where I don’t want the action to proceed. In the end, here is what I ended with:

class OrganizationController < ApplicationController
  before_filter :check_and_load_organization

  def show
     # stuff goes here
  end

  def roster_list
     # stuff goes here
  end

  def service_list
     # stuff goes here
  end

  def planner_list
     # stuff goes here
  end

  protected

  def check_and_load_organization
    if params["id"]
      begin
        @org = Organization.find(params["id"])
      rescue
        error_page("Organization not found") and return false
      end
    else
      error_page("Id is required") and return false
    end

    return true
  end

The nice thing is that now, when any of my actions have the filter applied (all actions for this example), the instance variable @org is available and known to be non-nil and valid. Here is a simple version of the show action to demonstrate this:

  def show
     render_text @org.id and return
  end

While I put this code into my OrganizationController, the function, and even the before_filter declaration, could have been in my ApplicationController. This would be useful if all controllers used the same model, but is probably not the case for most projects.

Finally, I plan to write another filter that can then perform authorization to ensure that the user trying to reach these actions are administrators and belong to the organization.

Technorati Tags: , ,

James @ June 17, 2006

Leave a comment


Feed Contact Us