With the following code :
class TestsController < ApplicationController
skip_before_filter :load_something, # how to skip these only
:load_something_else # if the request is xhr ?
def index
respond_to do |format|
format.html
format.js
end
end
end
Is there a way to skip before filters depending if the request is a javascript call without changing the :load_something
and :load_something_else
methods ?
Thanks !
Try this line to skip the filtering by a condition:
skip_before_filter :load_something, :load_something_else,
:if => proc { request.xhr? }
For ruby-2.0 you can also use lambdas (which have a strictness in argument passing):
skip_before_filter :load_something, :load_something_else,
if: -> { request.xhr? }
or with an argument:
skip_before_filter :load_something, :load_something_else,
if: ->(arg) { request.xhr? && arg }
There used to be no clean solution to this. Assuming you do not have control over the before_filters
(or do not want to change them), i would leave the skip_before_filter
and add an extra before_filter
that only executes the wanted methods if it is an xhr
method.
So something like
skip_before_filter :load_something, # how to skip these only
:load_something_else # if the request is xhr ?
before_filter :do_loads_if_xhr
def do_loads_if_xhr
if request.xhr?
load_something
load_something_else
end
end
The method described here only works because the conditional is global for the application: the conditional is only evaluated when the class is created. Not on each request.
[UPDATED]
There is however, a cleaner way to make the skip_before_filter
conditional. Write it like this:
skip_before_filter :load_something, :load_something_else, :if => proc {|c| request.xhr?}
Also note that while skip_before_filter
is still completely supported, and not deprecated, since rails 4 the documentation seems to prefer the (identical) skip_before_action
. Also the documentation is totally not clear about this, had to verify in code.
All of these answers take the wrong approach in my opinion. Using a skip_before_action with a condition is doing it backwards, and isn't as explicit and clear as adding the condition to the before_action itself; so this is my proposal:
before_action :require_password_change, unless: -> { request.xhr? }
This way, to someone reading your code it's immediately clear under what conditions this before_action runs or doesn't run, without having to rely on them happening across this skip_before_action somewhere in the controller hierarchy.
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