Using Ruby hooks to combine two modules into one
I had a combination of class and instance methods that I wanted to include into a model in Rails. The normal approach to do this would be to move all the instance methods into a module called
Updateable and all the class methods into another module called
UpdateableClassMethods - and then to use
extend to make it available to the model. Example below:
class ProductTag < ApplicationRecord include Updateable extend UpdateableClassMethods end
Although this is good, I came across Ruby hooks which can improve this.
Hooks is a code that gets called to tell you that something is about to happen, or has happened. For example, the
included hooks tells you when a class has gained a subclass.
By using the
included hook we can know when a module is added to a class. So in the above example, we can use the
included hook to know when the
Updateable module is added to the
ProductTag class. From here, it is easy to mix in the class methods also into the same module like below.
As you can see in the image above, I have an
included method in the module which lets me know anytime the module is included in the class!
def self.included(host_class) host_class.extend(ClassMethods) end
This doesn't seem like much but I found that it's a good way to keep my code clean.