Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to append a before_filter in gem after all other controller before_filters in a Rails3 app?

There's a gem, which appends a before_filter to a Rails app:

class Railtie < Rails::Railtie
  initializer "..." do
    ActiveSupport.on_load(:action_controller) do
      ActionController::Base.send(:include, Filter)

...

module Filter
  extend ActiveSupport::Concern

  included do
    append_before_filter :set_locale
  end

  def set_locale
     ....

And here's some controller in the app:

class DesktopsController < ApplicationController
  before_filter :set_language_in_session

Now the problem with this is that the before_filter from the gem is being put in the filter chain before the before_filter from the DesktopsController:

DesktopsController._process_action_callbacks.select { |c| c.kind == :before }.collect { |filter| filter.filter }
=> [
    [0] :set_locale,
    [1] :set_language_in_session
]

How can I make the before_filter from the gem (set_locale) be put after all other filters? The secret probably lies in this line:

ActiveSupport.on_load(:action_controller) do

But I've tried different libraries without any luck...

Btw. Here's the full code of the gem. Ruby 1.9.2, Rails 3.0.5.

like image 761
Paweł Gościcki Avatar asked Sep 16 '11 15:09

Paweł Gościcki


People also ask

Where should you add filter code in Rails?

Rails after filters are executed after the code in action controller is executed. Just like before filters, after filters are also defined at the top of a controller class that calls them. To set it up, you need to call after_filter method.

What does Before_action do in Rails?

When writing controllers in Ruby on rails, using before_action (used to be called before_filter in earlier versions) is your bread-and-butter for structuring your business logic in a useful way. It's what you want to use to "prepare" the data necessary before the action executes.

What is application controller in Rails?

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.

What is before action?

A 'before action review' (BAR) is a tool to help a team asses the current knowledge and experience they already have as a way to inform the planning stages of a new project.


1 Answers

Adapting the gem will never work. The gem is initialised as one of the first things in the rails process, so before any actual controller is ever launched. So this means, that whatever you do, most likely the filter from the gem will still remain the first gem.

So the only solutions I see are:

  • using prepend_before_filter in your own controllers for those actions that need to come before the set_locale.
  • if you need explicit control, use the skip_before_filter and explicit before_filter.

In a rails 2 application, we devised a hack to make sure that some filter was run as last filter, by overriding the perform_action_without_filters (see Is there a way to force a before_filter to always execute last?) but we removed that when upgrading to rails 3.

like image 127
nathanvda Avatar answered Sep 28 '22 09:09

nathanvda