Before_filter Order in Rails

A typical way to add before filter to controllers in Rails is use the codes like this in controllers

class ApplicationController < ActionController::Base
  before_filter :login_required
  ...
end

And if we declare more than one before filter, they are put into an array and form a filter chain. “filter_chain” is a class inheritable attribute of controller class, so you could use this line in Rails console to check what filters are working for a certain controller.

c: \> ruby script\console
>> puts Services::AdvertiserController.filter_chain.
>>   map(&:filter).join("\n")
login_required
......
authorize
=> nil
>>

But sometimes plugins and other codes will try to add before_filter in a tricky way.

  ActionController::Base.send :before_filter, :authorize

When the 2 declaration ways of before_filter mix together, it’s easy to be confused the order of before filters… For example, the “login_required” filter should work before “authorize” (check permissions of a user). But if I enable authorize before_filter in a “init.rb” file of a plugin, it will probably work before “login_required”.

And if you add a before_filter twice, it will appear in the filter chain twice. If you want to make sure a filter runs after another, a dirty trick is

skip_before_filter :login_required, :authorize
before_filter :login_required, :authorize

But this will make ppl confused even faster.

By the way, the plugin load order in Rails 1.2.x is not reliable either. Here is an intro about it, and Rails 2.0 has improved this feature.

So, my conclusion about before_filter, a best practice, is to avoid enabling before_filter in plugins or lib files, just provide the before_filter and let the app developers decide when and in what order to enable it.

One thought on “Before_filter Order in Rails”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.