如何在Rails 4中使用关注点
默认的Rails 4项目生成器现在在控制器和模型下创建目录“关注”。 我已经找到了关于如何使用路由问题的一些解释,但没有涉及到控制器或模型。
我很确定它与社区中目前的“DCI趋势”有关,并且想尝试一下。
问题是,我该如何使用此功能,是否有一个关于如何定义命名/类层次结构以使其工作的约定? 我如何在模型或控制器中包含关注点?
所以我自己发现了它。 它实际上是一个非常简单但强大的概念。 它与代码重用有关,如下例所示。 基本上,这个想法是提取常见的和/或上下文特定的代码块,以清理模型,避免它们变得过于肥胖和混乱。
作为一个例子,我会把一个众所周知的模式,标签模式:
# 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
因此,遵循产品示例,您可以将Taggable添加到您所需的任何类并共享其功能。
DHH很好地解释了这一点:
在Rails 4中,我们将邀请程序员使用关于默认应用程序/模型/关注点和应用程序/控制器/关注目录的问题,这些目录自动成为加载路径的一部分。 与ActiveSupport :: Concern包装器一起,它足以支持这个轻量级因式分解机制。
我一直在阅读关于使用模型问题来皮肤化肥胖模型以及干起你的模型代码。 以下是一些例子的解释:
1)烘干型号代码
考虑文章模型,事件模型和评论模型。 文章或事件有很多评论。 评论属于文章或事件。
传统上,模型可能如下所示:
评论型号:
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
正如我们注意到的,Event和Article都有一个共同的重要代码。 使用关注点,我们可以在一个单独的可评论模块中提取此通用代码。
为此,在app / models /关注点中创建一个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
end
2)皮肤化脂肪模型。
考虑事件模型。 一个事件有很多参加者和评论。
通常,事件模型可能如下所示
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
有许多关联的模型,否则就会积累越来越多的代码并变得难以管理。 关注提供了一种方法来对脂肪模块进行皮肤润色,使它们更加模块化,易于理解。
上述模型可以使用以下关注点进行重构:在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
end
commentable.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
*在使用问题时,建议采用基于“域”的分组而不是“技术”分组。 基于域的分组类似于“可评论的”,“可照片的”,“可参与的”。 技术分组将意味着'验证方法','FinderMethods'等
值得一提的是,使用问题被许多人认为是不好的主意。
一些原因:
include
方法,还有一个完整的依赖关系处理系统 - 对于那些旧式的Ruby混合模式来说太复杂了。 担心是简单的方法在腿上射击自己,小心他们。
链接地址: http://www.djcxy.com/p/8283.html上一篇: How to use concerns in Rails 4
下一篇: How can I rename a database column in a Ruby on Rails migration?