murphyslaw
murphyslaw

Reputation: 636

How to skip a before filter custom class in Ruby on Rails?

I have a Ruby on Rails Controller with a before_filter using a custom class:

class ApplicationController
  before_filter CustomBeforeFilter      
end

I have another controller inherited from ApplicationController, where I would like to skip the CustomBeforeFilter:

class AnotherController < ApplicationController
  skip_before_filter CustomBeforeFilter
end

That doesn't work. The before_filter is still executed.

How can I skip a Ruby on Rails before filter that uses a custom class?

Upvotes: 3

Views: 1212

Answers (3)

Peter Brown
Peter Brown

Reputation: 51707

Class callbacks are assigned a random callback name when they are added to the filter chain. The only way I can think of to do this is to find the name of callback first:

skip_before_filter _process_action_callbacks.detect {|c| c.raw_filter == CustomBeforeFilter }.filter

If you want something a little cleaner in your controllers, you could override the skip_before_filter method in ApplicationController and make it available to all controllers:

class ApplicationController < ActionController::Base
  def self.skip_before_filter(*names, &block)
    names = names.map { |name|
      if name.class == Class
        _process_action_callbacks.detect {|callback| callback.raw_filter == name }.filter
      else
        name
      end
    }

    super
  end
end

Then you could do:

class AnotherController < ApplicationController
  skip_before_filter CustomBeforeFilter
end

Upvotes: 2

Erez Rabih
Erez Rabih

Reputation: 15788

Simplest solution would be to return from your before_filter method if the current controller is the one you want to skip:

class CustomBeforeFilter
  def self.filter(controller)
    return if params[:controller] == "another"
    # continue filtering logic
  end
end

EDIT:

Following phoet advice you can also use controller.controller_name instead of params[:controller]

Upvotes: 1

phoet
phoet

Reputation: 18845

you could just wrap your custom class in a method like so:

before_filter :custom
def custom
  CustomBeforeFilter.filter(self)
end

and then disable that filter wherever you want

Upvotes: 2

Related Questions