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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 00:30:26  来源:igfitidea点击:

Is there a way in Rails to skip a before_filter if the request is xhr?

ruby-on-rails

提问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.

我认为这应该有效。