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}}。
答案 0 :(得分:1)
这是我的看法:
你可以想到&#34;包括&#34;比如将模块作为参数的方法;为了包含模块,模块必须已经由环境加载;否则该线会因缺少常量错误而失败。
因此,当调用include AbstractController::Layouts
时,必须在AbstractController或顶级命名空间中加载布局才能使其生效。
在actionpack源代码中查看,事实证明Layouts 是自动加载的,这可以确保它在&#34; include&#34;之前加载。线完成。
由于extend ActiveSupport::Concern
,append_features
覆盖将在<#34>包含&#34时可用 ; ActionController :: Base中的行已经完成执行。
在此之后,将使用ActionController :: Base作为参数执行Layouts的append_features方法。