views:

247

answers:

2

I'm at Rails 2.3.5 and I have this problem:

class BaseController < ApplicationController
  before_filter :foo, :only => [:index]
end

class ChildController < BaseController
  before_filter :foo, :only => [:index, :show, :other, :actions]
end

The problem is that on ChildController, the :foo before filter gets called twice.

I've tried a number of workarounds around this problem. If I don't include the :index action in the child, it never gets called for that action.

The solution I found works, but I think it's very very ugly

skip_before_filter :foo
before_filter :foo, :only => [:index, :show, :other, :actions]

Is there a better way to solve this problem?

+6  A: 

"This behavior is by design".

The Rails guide on controllers states:

"Filters are inherited, so if you set a filter on ApplicationController, it will be run on every controller in your application."

This explains the behaviour you're seeing. It also suggests the exact same solution you propose (using skip_before_filter) to define which filters will or will not be run for a particular controller and/or methods.

So, ugly or not, seems like the solution you found is common and approved practice.

http://guides.rubyonrails.org/action_controller_overview.html#filters

Roadmaster
+2  A: 

If you don't want to use skip_before_filter you could always skip the index action in the ChildController:

class ChildController < BaseController
  before_filter :foo, :only => [:show, :other, :actions]
end

But this might become a problem if you change the behavior in BaseController and remove the filter from the index action. Then it would never be called so using skip_before_filter might be a better idea.

Tomas Markauskas