Its over the ninth week in GSoC 2016 and here I am with another of my blog post. Today I will discuss about a pretty nice thing that I learnt while I was working with the notification system. It is related to writing DRY code by using of modules.
My mentor Jeff said that methods in some models were becoming repetitive and they were doing the same kind of task. So it would be better if we could keep the code DRY i.e. avoid redundancy in code. DRY stands for Don’t Repeat Yourself i.e. try to avoid repetitive code in a application. We can do this by creating methods and modules. Ruby has an awesome concept of modules and mixins for this purpose.
ActiveSupport Concerns follow the same principle of Ruby modules and by extending them on Rails models we can include common methods that are shareable across various models.
We had two models named Node and Answer models. A Node basically served as a container of posts like wikis, questions and research notes in publiclab.org. Answer as the name suggests are answers to questions. Both have some common methods named liked
and liked_by
. So we made a NodeShared
concern and put those in them. Here is how the concern looks like
This file goes in a separate app/models/concerns/
directory. This is where all concerns reside. To define it as a concern you need to extend
the ActiveSupport::Concern
module as I did above. After that after you have defined the concern you can use it in others models by including the concern like include NodeShared
in this case. Here is how the node model would look
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Node < ActiveRecord::Base | |
include NodeShared # This includes the NodeShared Concern | |
attr_accessible :title, :uid, :status, :type, :vid, :cached_likes, :comment, :path, :slug | |
self.table_name = 'node' | |
self.primary_key = 'nid' | |
has_many :node_selections, :foreign_key => :nid | |
has_many :answers, :foreign_key => :nid | |
def latest | |
self.revisions | |
.where(status: 1) | |
.first | |
end | |
def revisions | |
self.drupal_node_revision | |
.order("timestamp DESC") | |
end | |
end |
This is a small part of the actual model used. So now the methods in the concern become a part of the model and they can be called with an instance of Node
model. Now suppose the Answer
model also needs the similar methods. We can simply add this concern to the model as well instead of writing the methods over again.
DHH the creator of Ruby on Rails explained this in his blog post.
Coming back to my progress in Summer of Code I have started working on UI changes and modified views that will include some good features. I will discuss them in my future posts. You can look at my PR #628 though it is Work in progress now. As the mid of July is over its probably going to be more work in the next couple of weeks as things are nearing the end.