ActiveSupport :: Concern vs append_features

时间:2012-09-22 18:39:05

标签: ruby ruby-on-rails-3 activesupport

ActiveSupport::Concern个问题上有an article个问题。这是Rails中的一个有效实现:

module ActionController
  class Base < Metal
    include AbstractController::Layouts
  end
end

module AbstractController
  module Layouts
    extend ActiveSupport::Concern

    include Rendering

    included do
      class_attribute :_layout, :_layout_conditions, :instance_accessor => false
      self._layout = nil
      self._layout_conditions = {}
      _write_layout_method
    end

    module ClassMethods
      ...
    end
  end
end

module AbstractController
  module Rendering
    extend ActiveSupport::Concern

    included do
      class_attribute :protected_instance_variables
      self.protected_instance_variables = []
    end

    module ClassMethods
      ...
    end
  end
end

extend如何在Layouts ruby​​挂钩之前执行append_features调用?必须先执行extend。毕竟,它的全部意义是劫持append_features ruby​​默认值并重新实现它。但是,根据Ruby文档,append_features在您将此模块(例如AbstractController::Layouts)包含在另一个模块(例如ActionController::Base)后立即执行。所以这里有困惑。如果是这种情况,则永远不会调用覆盖的append_features ActiveSupport::Concern {{1}}。

1 个答案:

答案 0 :(得分:1)

这是我的看法:

你可以想到&#34;包括&#34;比如将模块作为参数的方法;为了包含模块,模块必须已经由环境加载;否则该线会因缺少常量错误而失败。

因此,当调用include AbstractController::Layouts时,必须在AbstractController或顶级命名空间中加载布局才能使其生效。

在actionpack源代码中查看,事实证明Layouts 是自动加载的,这可以确保它在&#34; include&#34;之前加载。线完成。

由于 时执行extend ActiveSupport::Concernappend_features覆盖将在<#34>包含&#34时可用 ; ActionController :: Base中的行已经完成执行。

在此之后,将使用ActionController :: Base作为参数执行Layouts的append_features方法。