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?
Module#included allows modules to inject both class and instance methods, and execute associated code, from a single include. The documentation for ActiveSupport::Concern illustrates a typical use. It's injecting class methods into the calling class, and executing code. In this case, adding a scope.
Actually, Ruby facilitates the use of composition by using the mixin facility. Indeed, a module can be included in another module or class by using the include , prepend and extend keywords.
In simple words, the difference between include and extend is that 'include' is for adding methods only to an instance of a class and 'extend' is for adding methods to the class but not to its instance.
In Ruby, modules are somewhat similar to classes: they are things that hold methods, just like classes do. However, modules can not be instantiated. I.e., it is not possible to create objects from a module. And modules, unlike classes, therefore do not have a method new .
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
and second_method
are included as instance-methods of MyClass.
instance = MyClass.new instance.first_method # => whatever returned value of first_method is
The methods of ClassMethods
are automatically mixed as class methods of MyClass
. This is a common Ruby pattern, that ActiveSupport::Concern
encapsulates. The non-Rails Ruby code is
module 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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With