如果请求是xhr,Rails中有没有办法跳过before_filter?

jri*_*lai 15 ruby-on-rails

使用以下代码:

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
Run Code Online (Sandbox Code Playgroud)

有没有办法在过滤器之前跳过,具体取决于请求是否是javascript调用而不更改:load_something:load_something_else方法?

谢谢 !

Мал*_*евъ 38

尝试使用此行来跳过条件过滤:

skip_before_filter :load_something, :load_something_else,
   :if => proc { request.xhr? }
Run Code Online (Sandbox Code Playgroud)

对于你也可以使用lambdas(在参数传递中有严格性):

skip_before_filter :load_something, :load_something_else,
   if: -> { request.xhr? }
Run Code Online (Sandbox Code Playgroud)

或者带有参数:

skip_before_filter :load_something, :load_something_else,
   if: ->(arg) { request.xhr? && arg }
Run Code Online (Sandbox Code Playgroud)


nat*_*vda 20

以前没有干净的解决方案.假设您无法控制before_filters(或者不想更改它们),我会留下skip_before_filter并添加一个额外的before_filter,如果它是一个xhr方法,只执行想要的方法.

所以像

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
Run Code Online (Sandbox Code Playgroud)

此处描述的方法仅起作用,因为条件对于应用程序是全局的:条件仅在创建类时进行评估.不是每个请求.

[更新]然而,有一个更清洁的方式来制定skip_before_filter条件.写这样:

skip_before_filter :load_something, :load_something_else, :if => proc {|c| request.xhr?}
Run Code Online (Sandbox Code Playgroud)

另请注意,虽然skip_before_filter仍然完全支持,而不是弃用,因为rails 4文档似乎更喜欢(相同)skip_before_action.此外,文档对此完全不清楚,必须在代码中进行验证.


Mik*_*ell 13

在我看来,所有这些答案都采用了错误的方法.使用带有条件的skip_before_action是向后执行的,并且不像将条件添加到before_action本身那样明确和清楚; 所以这是我的建议:

before_action :require_password_change, unless: -> { request.xhr? }
Run Code Online (Sandbox Code Playgroud)

通过这种方式,对于读取代码的人,可以立即清楚这个before_action在什么条件下运行或不运行,而不必依赖于它们在控制器层次结构中的某个skip_before_action中发生.