Ruby-on-rails 如果请求是 xhr,Rails 有没有办法跳过 before_filter?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5114529/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a way in Rails to skip a before_filter if the request is xhr?
提问by jrichardlai
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_somethingand :load_something_elsemethods ?
有没有办法在过滤器之前跳过取决于请求是否是 javascript 调用而不更改:load_something和:load_something_else方法?
Thanks !
谢谢 !
回答by Малъ Скрылевъ
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.0you can also use lambdas (which have a strictness in argument passing):
对于ruby-2.0,您还可以使用 lambdas(在参数传递方面具有严格性):
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 }
回答by nathanvda
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_filterand add an extra before_filterthat only executes the wanted methods if it is an xhrmethod.
过去没有干净的解决方案。假设您无法控制before_filters(或不想更改它们),我会离开skip_before_filter并添加一个额外的before_filter,如果它是一个xhr方法,则只执行所需的方法。
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 hereonly 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_filterconditional. Write it like this:
[更新] 然而,有一种更简洁的方法来设置skip_before_filter条件。像这样写:
skip_before_filter :load_something, :load_something_else, :if => proc {|c| request.xhr?}
Also note that while skip_before_filteris 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.
另请注意,虽然skip_before_filter仍完全受支持,但并未弃用,因为 rails 4 文档似乎更喜欢 (identical) skip_before_action。此外,文档对此完全不清楚,必须在代码中进行验证。
回答by Mike Campbell
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:
在我看来,所有这些答案都采用了错误的方法。使用带有条件的skip_before_action 是向后执行,并且不像将条件添加到before_action 本身那样明确和清晰;所以这是我的建议:
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.
这样,对于阅读您的代码的人来说,在什么条件下这个 before_action 运行或不运行的情况下会立即清楚,而不必依赖它们在控制器层次结构中某个地方的这个 skip_before_action 中发生。
回答by rewritten
Use alias_method_chainto decorate the filters, so they aren't executed if the request is xhr.
使用alias_method_chain装饰过滤器,因此,如果该请求是XHR他们没有执行。
def load_something_with_noxhr(*args)
load_something_without_noxhr(*args) unless request.xhr?
end
alias_method_chain :load_something, :noxhr
(change load_somethinginto whatever needed, the _with_and _without_are literal, and the suffix noxhrmust be the same you pass as second argument in the alias_method_chaincall.)
(更改load_something为任何需要的,_with_和_without_是文字,后缀noxhr必须与您在alias_method_chain调用中作为第二个参数传递的相同。)
回答by pablorc
You coded that filters? In that case you can write an ifclause inside them without using skip_before_filter:
你编码的过滤器?在这种情况下,您可以if在其中编写一个子句而无需使用skip_before_filter:
def load_something
unless request.xhr?
#Code
end
end
In the other hand, you can make yout own filter and delegate:
另一方面,您可以创建自己的过滤器和委托:
before_filter :my_own_filter
def my_own_filter
unless request.xhr?
load_something
load_something_else
end
end
I think this should work.
我认为这应该有效。

