Friday, 2 September 2016

How to use concerns in Rails 4



The default Rails 4 project generator now creates the directory "concerns" under controllers and models. I have found some explanations about how to use routing concerns, but nothing about controllers or models.



I am pretty sure it has to do with the current "DCI trend" in the community and would like to give it a try.



The question is, how am I supposed to use this feature, is there a convention on how to define the naming / class hierarchy in order to make it work? How can I include a concern in a model or controller?


Answer



So I found it out by myself. It is actually a pretty simple but powerful concept. It has to do with code reuse as in the example below. Basically, the idea is to extract common and / or context specific chunks of code in order to clean up the models and avoid them getting too fat and messy.




As an example, I'll put one well known pattern, the taggable pattern:



# app/models/product.rb
class Product
include Taggable

...
end


# app/models/concerns/taggable.rb
# notice that the file name has to match the module name
# (applying Rails conventions for autoloading)
module Taggable
extend ActiveSupport::Concern

included do
has_many :taggings, as: :taggable
has_many :tags, through: :taggings


class_attribute :tag_limit
end

def tags_string
tags.map(&:name).join(', ')
end

def tags_string=(tag_string)
tag_names = tag_string.to_s.split(', ')


tag_names.each do |tag_name|
tags.build(name: tag_name)
end
end

# methods defined here are going to extend the class, not the instance of it
module ClassMethods

def tag_limit(value)
self.tag_limit_value = value

end

end

end


So following the Product sample, you can add Taggable to any class you desire and share its functionality.



This is pretty well explained by DHH:





In Rails 4, we’re going to invite programmers to use concerns with the
default app/models/concerns and app/controllers/concerns directories
that are automatically part of the load path. Together with the
ActiveSupport::Concern wrapper, it’s just enough support to make this
light-weight factoring mechanism shine.



No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...