A couple week ago, while I was developing the active_record_uuid gem, I need to do extension to the existing methods in
active_record library. The first one is to send
portal_uuid instead of
portal_id in the association methods such as
has_many, …. The second one is about quoting
uuid value and send it to
mysql. I went to see the source code of
active_record to find where the best place to do my job. After spending some times to understand the codebase, I find the place to overwrite,
ActiveRecord::ConnectionAdapters::Quoting. The first thing that comes to my head is to do
alias_method_chain of these methods. I didn’t think much, write the test and implement it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
Read that code again, I realized there are two things that my code could be changed in the future. Those are the module and method’s name. If one day the
Rails team decide to change the module name, then I would have to do another commit to fix that. In addition, method name is a bit longer and cumbersome as well.
I took one step back and think about it again. That module is simply included into
ActiveRecord::Base. From here, it reminds about my ruby lesson. Ruby method lookup path is the reverse order of module inclusion. Why Ruby does that? Well, it is because it is designed to be extensible.
Therefore, if I define another module and include it very last, my method should be run before the original method. That’s cool, isn’t it? Calling the original version is even easier, call
#super will does the job. It’s awesome.
1 2 3 4 5 6 7 8 9 10 11 12
The question arrives to my head. What is the use of
alias_method_chain? What is it for? Well, in the above case, I wouldn’t need it, but it’s still useful to overwrite the methods which are defined originally in that class.
1 2 3 4 5 6 7 8 9 10 11
There is no use if I
Person class, because Ruby will run the method inside that class, then the method inside the module. In this case, only
alias_method_chain could help.
It’s hard to see any good guidelines to do extensions when developing the gem, but here it’s a better way to do the job.