有一个模块MyModule:
module MyModule
extend ActiveSupport::Concern
def first_method
end
def second_method
end
included do
second_class_method
end
module ClassMethods
def first_class_method
end
def second_class_method
end
end
end
Run Code Online (Sandbox Code Playgroud)
当某个类include是这个模块时,它将有2个方法暴露为实例方法(first_method和second_method)和2个类方法(first_class_method和second_class_method) - 很明显.
有人说,那
included块将在包含模块的类的上下文中执行.
这究竟是什么意思?意思是,什么时候second_class_method执行这个方法()?
Sim*_*tti 69
这是一个实际的例子.
class MyClass
include MyModule
end
Run Code Online (Sandbox Code Playgroud)
当您将模块包含在类中时,included将调用钩子.因此,second_class_method将在范围内调用Class.
这里发生的是
first_method并second_method作为实例方法包含在内MyClass.
instance = MyClass.new
instance.first_method
# => whatever returned value of first_method is
Run Code Online (Sandbox Code Playgroud)这些方法ClassMethods自动混合为类方法MyClass.这是一种常见的Ruby模式,它是ActiveSupport::Concern封装的.非Rails Ruby代码是
module MyModule
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def this_is_a_class_method
end
end
end
Run Code Online (Sandbox Code Playgroud)
结果如何
MyClass.this_is_a_class_method
Run Code Online (Sandbox Code Playgroud)
或者在你的情况下
MyClass.first_class_method
Run Code Online (Sandbox Code Playgroud)included 是一个有效地对以下代码的钩子
# non-Rails version
module MyModule
def self.included(base)
base.class_eval do
# somecode
end
end
end
# Rails version with ActiveSupport::Concerns
module MyModule
included do
# somecode
end
end
Run Code Online (Sandbox Code Playgroud)
对于常见的模式,它主要是"语法糖".在实践中发生的是,当您混合模块时,该代码在混合器类的上下文中执行.
Ner*_*min 17
included当你包含module在一个类中时,它被用来定义关系,范围,验证,......它甚至在你从该类创建对象之前被调用.
例
module M
...
included do
validates :attr, presence: true
has_many :groups
end
...
end
Run Code Online (Sandbox Code Playgroud)