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.