Rails 关于子类复用父类 before_fitler 的问题

itsvoid · 2013年03月28日 · 最后由 itsvoid 回复于 2013年03月28日 · 2638 次阅读

父类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]
共收到 19 条回复
before_filter :x, only: [A, B, C, D]  
or
before_filter :x, except: [E, F, G]

#1楼 @zgm 你这个解不了我的问题。 子类继承了父类的before_fitler。而子类有新方法同样需要父类的这个before_filter x。

我需要在子类中,对before_filter x 增加 一个action D

#3楼 @afeicool 我是要复用父类的before_filter X,而不是另写一个。

#2楼 @itsvoid 不是没理解你的需求, 只是你说的需求没办法实现。

@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

#8楼 @quakewang 这个 cool 啊

是否可以换一个思路:

class ChildController
  before_filter :y, only: [:D]

  protected
  def y; x; end
end

在我看来, ChildController 了解 ParentController 中有 x 是必然的,但不是太应该让它去关心其他 actions 。

未测试,仅供讨论参考。

不明白! 直接在子类里面使用 before_filter :x, only: [:D] 不行吗?

#11楼 @zlx_star 子类还有其他从父类继承而来的action,比如A,B,C。如果像你这样写,子类的A,B,C就无法应用X了

#8楼 @quakewang 有点过于hack了。子类复用父类过滤器,同时应用到子类自己新的action上,这应该是一个很普遍的需求阿。

#10楼 @ashchan 这个方法我也想过,不过总得要增加1个函数,而且这个函数还仅仅是调用父类的X

#15楼 @hysios 什么意思?

#16楼 @itsvoid 不要管父类,直接在子类里面使用 before_filter :x, only: [:A, :B, :C, :D]

@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

#18楼 @hysios 如何子类这样写 before_filter :x , only: [:d], 子类的a,b,c方法都不会运用x了。你可以试试。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册