Ruby modules - included do end block
There is a module 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
When some class include
s this module, it will have 2 methods exposed as instance methods (first_method
and second_method
) and 2 class methods (first_class_method
and second_class_method
) - it is clear.
It is said, that
included
block will be executed within the context of the class that is including the module.
What does it mean exactly? Meaning, when exactly would this method (second_class_method
) be executed?
Solution 1:
Here's a practical example.
class MyClass
include MyModule
end
When you will include the module in a class, the included
hook will be called. Therefore, second_class_method
will be called within the scope of Class
.
What happens here is
-
first_method
andsecond_method
are included as instance-methods ofMyClass.
instance = MyClass.new instance.first_method # => whatever returned value of first_method is
-
The methods of
ClassMethods
are automatically mixed as class methods ofMyClass
. This is a common Ruby pattern, thatActiveSupport::Concern
encapsulates. The non-Rails Ruby code ismodule MyModule def self.included(base) base.extend ClassMethods end module ClassMethods def this_is_a_class_method end end end
Which results in
MyClass.this_is_a_class_method
or in your case
MyClass.first_class_method
-
included
is a hook that is effectively to the following code# 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
It's mostly "syntactic sugar" for common patterns. What happens in practice, is that when you mix the module, that code is executed in the context of the mixer class.
Solution 2:
included
is called when you include module
into a class, it is used for defining relations, scopes, validations, ...
It gets called before you even have created object from that class.
example
module M
...
included do
validates :attr, presence: true
has_many :groups
end
...
end