In this fifteenth part of an eighteen-part series on the Action Pack library for Rails, you'll start learning how and why to use control filters. This article is excerpted from chapter six of the book Beginning Rails: From Novice to Professional, written by Jeffery Allan Hardy, Cloves Carneiro Jr. and Hampton Catlin (Apress; ISBN: 1590596862).
Filters provide a way for you to perform operations either before or after an action is invoked. There’s even an around filter that can wrap the executing of an action. Of the three, the before filter is the most commonly used, so that’s what we’ll focus on here.
Here’s how it works: all the code you place in a before_filter will be run before the action in question is called. Pretty simple, really. But there’s a catch: if the before_ filter returns false, the action will not be executed. We often use this to protect certain actions that require a login. In our users controller, we want the new , create , login , and logout actions to remain open (anyone can access them), but we want to restrict all other actions to logged-in users. Here’s how we can do that using filters:
class UsersController < ApplicationController
before_filter :authenticate, :except => [:new, :create, :login, :logout] end
This will cause the authenticate method to be run before every action except those listed. Assume the authenticate method is defined on the application controller and is therefore available to every other controller in the system. If the authenticate method returns false, the requested action will not be executed, thereby protecting it from unauthorized visitors.
You can also use the :only modifier to specify that the filter is to run for only the given actions. We could have written the preceding example more concisely as follows:
before_filter :authenticate, :only => :show
Without the :only or :except modifiers, the filter will run for all actions.
Controller inheritance hierarchies share filters downwards, but subclasses can also add or skip filters without affecting the superclass. Let’s say you have applied a global filter to the application_controller , but you have a particular controller that you want to be exempt from filtration. You can use skip_before_filter , like this:
class ApplicationController < ActionController::Base
before_filter :authenticate_with_token end
class PublicController < ApplicationController
# We don't want to check for a token on this controller
skip_before_filter :authenticate_with_token end
Filters are a fairly involved topic, and we’ve only scratched the surface here. Still, we’ve shown you the most common usage pattern: protecting actions. For more information about filters, including usage examples, check out the Rails API documentation at http://api.rubyonrails.com/classes/ActionController/Filters/ClassMethods.html .