Ruby on Rails before_filter vs ruby​​的初始化

只是想到了我的想法。 以下是有什么区别的

的before_filter

class ApplicationController < ActionController::Base before_filter :foo def foo @mode = Model.new end end 

ruby初始化

 class ApplicationController < ActionController::Base def initialize foo end def foo @mode = Model.new end end 
  1. ruby的初始化方法是否在rails中按预期工作?
  2. 如果是,那么我们可以使用初始化filter必须应用于控制器中的所有操作吗?

对于每个请求,您确实获得了一个新的ApplicationController实例,但是这里的重要ActionController::Base#initialize是您试图覆盖ActionController::Base#initialize核心行为而不调用父行为。

 ApplicationController < ActionController::Base def initialize super # this calls ActionController::Base initialize init_foo end private def init_foo @foo = Foo.new end end 

这不是惯用的Rails行为。 他们给你before_filter是有原因的; 所以使用它。

我相信这是由Sandi Metz 在Ruby中的实用面向对象设计中介绍的 。

假设您正在为其他开发人员/用户设计基类,并希望允许他们挂钩过程中的各个步骤( 例如初始化)。通常,有两种方法:

  1. 将过程分解为小方法,并且(在文档中)提醒用户在覆盖方法时使用super
  2. 包含对用户可以使用自定义function覆盖的各种空挂钩方法的调用。

(我相信这些是模板方法模式的变体。)

第二种方式需要您付出更多努力,并为您的用户减少工作量。

在这种特定情况下, before_filter提供了一种更before_filter的方式来附加多个钩子,并鼓励您将钩子分解为具有有意义名称的单一责任方法。 这在使用更多控制器inheritance的应用程序中变得更加重要。