默认的Rails4项目生成器现在在控制器和模型下创建了目录"concerns“。我找到了一些关于如何使用路由问题的解释,但没有关于控制器或模型的解释。
我很确定这与当前社会上的"DCI潮流“有关,并愿意尝试一下。
问题是,我应该如何使用这个特性,是否有一个关于如何定义命名/类层次结构的约定,以便使其工作?如何在模型或控制器中包含关注点?
发布于 2013-02-26 06:50:30
所以我自己找出来了。这实际上是一个非常简单但强大的概念。它与代码重用有关,如下面的示例所示。基本上,这个想法是提取公共的和/或上下文特定的代码块,以便清理模型,避免它们变得太胖和混乱。
作为示例,我将使用一个众所周知的模式,即taggable模式:
# 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因此,按照Product示例,您可以将Taggable添加到您想要的任何类中,并共享其功能。
DHH很好地解释了这一点。
在Rails 4中,我们将邀请程序员使用默认的应用程序/模型/关注点和应用程序/控制器/关注点目录的关注点,这些目录会自动成为加载路径的一部分。再加上ActiveSupport::Concern包装器,就足以让这个轻量级的分解机制大放异彩了。
发布于 2014-09-16 06:50:59
我一直在读到关于使用模型关注点对胖模型进行皮肤处理以及使模型代码变干的文章。以下是示例的解释:
1) DRYing up模型代码
考虑一个文章模型、一个事件模型和一个评论模型。一篇文章或一个事件有很多评论。评论属于文章或事件。
传统上,模型可能如下所示:
评论模型:
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end文章模型:
class Article < ActiveRecord::Base
has_many :comments, as: :commentable
def find_first_comment
comments.first(created_at DESC)
end
def self.least_commented
#return the article with least number of comments
end
end事件模型
class Event < ActiveRecord::Base
has_many :comments, as: :commentable
def find_first_comment
comments.first(created_at DESC)
end
def self.least_commented
#returns the event with least number of comments
end
end正如我们所注意到的,有一段重要的代码对于事件和文章都是通用的。使用关注点,我们可以在一个单独的模块Commentable中提取这些公共代码。
为此,在app/models/concerns中创建一个commentable.rb文件。
module Commentable
extend ActiveSupport::Concern
included do
has_many :comments, as: :commentable
end
# for the given article/event returns the first comment
def find_first_comment
comments.first(created_at DESC)
end
module ClassMethods
def least_commented
#returns the article/event which has the least number of comments
end
end
end现在你的模型看起来像这样:
评论模型:
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end文章模型:
class Article < ActiveRecord::Base
include Commentable
end事件模型:
class Event < ActiveRecord::Base
include Commentable
end2)皮肤化脂肪模型。
考虑一个事件模型。一个事件有很多参与者和评论。
通常,事件模型可能如下所示
class Event < ActiveRecord::Base
has_many :comments
has_many :attenders
def find_first_comment
# for the given article/event returns the first comment
end
def find_comments_with_word(word)
# for the given event returns an array of comments which contain the given word
end
def self.least_commented
# finds the event which has the least number of comments
end
def self.most_attended
# returns the event with most number of attendes
end
def has_attendee(attendee_id)
# returns true if the event has the mentioned attendee
end
end具有许多关联的模型有积累越来越多代码的趋势,并且变得难以管理。关注点提供了一种对fat模块进行皮肤化的方法,使其更加模块化和易于理解。
可以使用如下关注点重构上述模型:在app/models/ concerns /event文件夹中创建一个attendable.rb和commentable.rb文件
attendable.rb
module Attendable
extend ActiveSupport::Concern
included do
has_many :attenders
end
def has_attender(attender_id)
# returns true if the event has the mentioned attendee
end
module ClassMethods
def most_attended
# returns the event with most number of attendes
end
end
endcommentable.rb
module Commentable
extend ActiveSupport::Concern
included do
has_many :comments
end
def find_first_comment
# for the given article/event returns the first comment
end
def find_comments_with_word(word)
# for the given event returns an array of comments which contain the given word
end
module ClassMethods
def least_commented
# finds the event which has the least number of comments
end
end
end现在使用关注点,您的事件模型简化为
class Event < ActiveRecord::Base
include Commentable
include Attendable
end*在使用关注点时,建议使用基于“域”的分组,而不是“技术”分组。基于域的分组类似于'Commentable','Photoable','Attendable‘。技术分组将意味着'ValidationMethods','FinderMethods‘等
发布于 2015-03-23 22:11:17
值得一提的是,许多人认为使用关注点是个坏主意。
一些原因:
在幕后有一些黑魔法在发生-关注的是修补pattern.
include类同样枯燥。如果你在不同的模块中填充50个公共方法并包含它们,你的类仍然有50个公共方法,只是你隐藏了代码的味道,把你的垃圾放在drawers.担心很容易让你伤到自己的腿,小心对待它们。
https://stackoverflow.com/questions/14541823
复制相似问题