当控制器被子类化时,为什么Rails before_filter被调用了两次?

时间:2010-05-24 16:10:55

标签: ruby-on-rails ruby inheritance actioncontroller before-filter

我在Rails 2.3.5并且遇到了这个问题:

class BaseController < ApplicationController
  before_filter :foo, :only => [:index]
end

class ChildController < BaseController
  before_filter :foo, :only => [:index, :show, :other, :actions]
end

问题是在ChildController上,过滤器被调用两次之前的foo。

我已经针对此问题尝试了一些解决方法。如果我没有在孩子中包含:index操作,则永远不会调用该操作。

我找到的解决方案有效,但我认为这非常非常丑陋

skip_before_filter :foo
before_filter :foo, :only => [:index, :show, :other, :actions]

有没有更好的方法来解决这个问题?

2 个答案:

答案 0 :(得分:15)

“此行为是设计使然”。

控制器上的Rails指南说明:

“继承过滤器,因此如果在ApplicationController上设置过滤器,它将在应用程序中的每个控制器上运行。”

这解释了您所看到的行为。它还建议使用完全相同的解决方案(使用skip_before_filter)来定义将为特定控制器和/或方法运行或不运行哪些过滤器。

所以,丑陋与否,似乎你找到的解决方案是常见且经过批准的实践。

http://guides.rubyonrails.org/action_controller_overview.html#filters

答案 1 :(得分:3)

如果您不想使用skip_before_filter,可以随时跳过index中的ChildController操作:

class ChildController < BaseController
  before_filter :foo, :only => [:show, :other, :actions]
end

但如果您更改BaseController中的行为并从index操作中删除过滤器,则可能会出现问题。然后它永远不会被调用,因此使用skip_before_filter可能是一个更好的主意。