views:

159

answers:

2

Hi there, in rails when you register filters in abstract superclasses they come before the filters registered in the controller class. Say I wanted to execute a method called authenticate as a filter right at the end of the filter chain. The only way I can figure it out is to declare that before_filter as the last filter in all my controller classes (and there are many of them). Is there a way to declare this filter in the superclass and have it still be executed last? The reason I want it executed last is that the controller class might modify the authentication requirements just for that controller, and I want these modifications to be taken into account before the final authentication filter is called.

A: 

Rails calls your ApplicationController first, before the local one... so you can do something like this (using your example):

In your Application controller you'll have your before_filter callback, and a corresponding method that gets called:

before_filter :authenticate


def authenticate
  # do something
end

In the controller for the resource type you're working with...

You can redefine / override authenticate

def authenticate
 # do something else
end

You can even choose NOT to use your authenticate callback for some methods

skip_before_filter :authenticate, :only => :my_method_without_auth
mylescarrick
Thanks for that but the authenticate method checks certain allowances to see if the current action is 'allowed'. These allowances are set up in another before filter that's called in the application controller. However, say I have a controller where I want to change the allowances further, that can only be triggered from the controller class, and in order for those allowances to be considered by authenticate, authenticate needs to run after the new allowances are set, thus authenticate needs to be declared in the controller class after the other before filter that mod's the allowances.
Brendon Muir
Why not have a single before_filter callback ... and use that method to set up everything you need in order?
mylescarrick
That idea isn't really workable. I think filters are there so that you can split out tasks in an understandable fashion. Besides this authentication method is run on every controller. These controllers all do different things.
Brendon Muir
A: 

Use prepend_before_filter in your controller classes instead of before_filter or append_before_filter.

Simone Carletti
Thanks for that suggestion too, but I've got a method in the abstract superclass that must run first, and so calling prepend_before_filter on the controller class will push that filter ahead of the one that must run first (it changes the database based upon the incoming url).
Brendon Muir
Probably the closest answer but doesn't really answer the original question. I don't think there's a way to do it in rails anyway.
Brendon Muir