On Github mdms-scott / concerns
"In computer science, separation of concerns (SoC) is a design principle for separating a computer program into distinct sections, such that each section addresses a separate concern. A concern is a set of information that affects the code of a computer program. A concern can be as general as the details of the hardware the code is being optimized for, or as specific as the name of a class to instantiate. A program that embodies SoC well is called a modular program... The value of separation of concerns is simplifying development and maintenance of computer programs. When concerns are well-separated, individual sections can be developed and updated independently. Of special value is the ability to later improve or modify one section of code without having to know the details of other sections, and without having to make corresponding changes to those sections."
# 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
Courtesy of stack overflow.
product = Product.new
product.tags_string = "green, large, shirt"
product.tags_string
=> "green, large, shirt"
product.tags
=> [{name: "green"}, {name: "large"}, {name: "shirt"}]
Product.tag_limit(5)
Well lets take a look:
module DateScopes
extend ActiveSupport::Concern
module ClassMethods
def include_date_scopes
define_singleton_method :"between" do |start_datetime, stop_datetime|
where ['created_at >= AND created_at <', start_datetime, stop_datetime]
end
define_singleton_method :"on_or_before_date" do |date|
where ['created_at <= ?', date]
end
end
end
end
class Article << ActiveRecord::Base include DateScopes include_date_scopes #... end
Article.between((Time.now - 7.days), Time.now) => #<ActiveRecord::Relation [...]> Article.between(Time.now, (Time.now + 7.days)) => #<ActiveRecord::Relation []> Article.on_or_before(Time.now - 7.years) => #<ActiveRecord::Relation []> Article.between(Time.now) => #<ActiveRecord::Relation [...]>
You can do many things with controller concerns:
module RescueExceptions
extend ActiveSupport::Concern
included do
rescue_from ::ActionView::MissingTemplate, :with => :handle_missing_page
rescue_from ::ActiveRecord::RecordNotFound, :with => :handle_missing_record
end
protected
def handle_missing_page(exception)
logger.error("#{exception.class.name}: #{exception.message} #{exception.backtrace.join("\n")}")
redirect_to your_404_path
end
def handle_missing_record(exception)
logger.error("#{exception.class.name}: #{exception.message} #{exception.backtrace.join("\n")}")
redirect_to your_missing_record_page
end
end