父类 ParentController 里面有一个 before_fitler x,应用在父类 action A,B,C 上。
Class ParentController
before_filter :x, only: [:A, :B, :C]
子类 ChildController 继承于 ParentController,但是有一个新 action D,同样需要将 x 应用在其 D 上,而且继承而来的 A,B,C 的 before_filter x 保留。
如果这样写:
before_filter :x, only: [:D]
那么,子类中 A,B,C 就没有 before_fitler X 了。
求解?
我需要的很像这样:
before_filter :x, add: [:D]
@itsvoid actionpack/lib/abstract_controller/callbacks.rb, line 33 或许你可以 hack 一下这个方法
我的需求是这样
Class ParentController
before_filter :x, only: [:A, :B, :C]
def A
end
def B
end
def C
end
protected
def x
...
end
end
Class ChildController < ParentController
before_filter :x, add: [:D]
end
但是,好像没有 add 这类方法。
不过,我理解这应该是一个比较普遍的需求,为什么 rails 的 before_filter 没有呢。
before_filter 接受 if 参数,用 proc 来处理
class ParentController
before_filter :x, if => proc {|controller| controller.filter_names_for_x.include?(action_name) }
def filter_names_for_x
[:A, :B, :C]
end
end
class ChildController
def filter_names_for_x
super << :D
end
end
是否可以换一个思路:
class ChildController
before_filter :y, only: [:D]
protected
def y; x; end
end
在我看来,ChildController
了解 ParentController
中有 x
是必然的,但不是太应该让它去关心其他 actions。
未测试,仅供讨论参考。
@itsvoid 直接用就是了 , before_filter 是基于 callbacks 的 参看 https://github.com/rails/rails/blob/master/actionpack/lib/abstract_controller/callbacks.rb#L81
@itsvoid 直接在子类加 before_filter :x , only: [:d] , 是没有问题的 因为每一个 before_filter :name ,即使相同名称 ,都会执行, 如果想跳过可以用 :skip_before_filter, 请查阅这段代码,你会发现 before_filter 实际是是调用 _insert_callbacks https://github.com/rails/rails/blob/master/actionpack/lib/abstract_controller/callbacks.rb#L178-L213