1

下面的代码显示了以不同顺序添加了 before_filters 的两个控制器。结果,控制器具有不同的行为。

当 current_user 为 nil 时(注销):

  • FooController -> 重定向到 login_path
  • BarController -> 重定向到 root_path

当然,您可以将这两种方法结合起来,让它们更智能,以使这个特定示例消失——但这没有抓住这个问题的重点。

手头的问题是,在 ActionController 中,添加过滤器的顺序是相关的。(你也可以争辩说那个实现不是最好的,但事实就是这样——所以让我们继续吧)

既然 ActionController 就是这样工作的,我想测试一下这种行为。但是,没有必要在每个单独的操作(不是 DRY)上测试之前过滤器的结果。据我所知,实际上重要的是每个 action 上过滤器链的结果顺序

唯一before_filter :require_user实际做的是将一个项目注入到回调链中——这就是我应该在我的子类中测试的全部内容——一个额外的项目已添加到链中。我不需要测试require_user对我的行为产生的影响——它们可以而且应该被存根。

说了这么多,问题来了:是否有一个公共 API 可以返回给定控制器和操作的过滤器链中的方法?这应该包括按适当顺序排列的过滤器之前、之后和周围。

class ApplicationController < ActionController::Base
  def require_user
    unless current_user
      redirect_to login_path and return
    end
  end
  def require_admin
    unless current_user.try(:admin?)
      redirect_to root_path and return
    end
  end
end

class FooController < ApplicationController
  before_filter :require_user
  before_filter :require_admin
end

class BarController < ApplicationController

  # reverse the order of the filters

  before_filter :require_admin
  before_filter :require_user
end
4

1 回答 1

0

您可以通过 _process_action_callbacks 类方法访问过滤器列表。对于过滤器列表,您可以:

FooController._process_action_callbacks.collect &:filter
于 2014-04-29T19:37:20.153 回答