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?
The Rails controller is the logical center of your application. It coordinates the interaction between the user, the views, and the model. The controller is also a home to a number of important ancillary services. It is responsible for routing external requests to internal actions.
There are three types of filters implemented in Rails: a before_filter runs before the controller action. an after_filter runs after the controller action. an around_filter yields to the controller action wherever it chooses.
Around Filters. Rails around filters contain codes that are executed both before and after controller's code is executed. They are generally used when you need both before and after filter. Its implementation is little bit different and more complex than other two filters.
"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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With