我正在使用Ruby on Rails 4.1,我希望“合并”两个has_many
模型关联的结果。也就是说,我有以下模型和协会:
class Article < ActiveRecord::Base
has_many :assigned_comments
has_many :unassigned_comments
end
class AssignedComment < ActiveRecord::Base
belongs_to :article
end
class UnassignedComment < ActiveRecord::Base
belongs_to :article
end
我想实施“某事”以便运行@article.comments
并让它返回@article.assigned_comments
和@article.unassigned_comments
这两个数据。
我该怎么做?有一些常见的做法?返回数据和数据库查询怎么样?
答案 0 :(得分:1)
如果AssignedComment
和UnassignedComment
具有相同的属性且状态assigned
可以更改为unassigned
,反之,为什么不添加和归因is_signed
到Comment
并执行以下操作:
class Article < ActiveRecord::Base
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :article
scope :assigneds, -> { where(is_signed: true) }
scope :unassigneds, -> { where(is_signed: false) }
end
使用范围,您可以@article.comments.assigneds
或@article.comments.unassigneds
,当然您只需执行@article.comments
即可获得属于comments
<的所有@article
< / p>
答案 1 :(得分:0)
has_many
创建的访问者返回ActiveRecord::Relation
,它基本上只是SQL查询的包装器。
您可以轻松编写一种方法,将关系的所有结果组合成一个数组。
def comments
self.assigned_comments.to_a + self.unassigned_comments.to_a
end
但这有几个缺点:
它始终将所有assigned_comments
和unassigned_comments
加载并初始化到内存中。
它没有任何ActiveRecord::Relation
方便的方法
根据AssignedComment
和UnassignedComment
列的相似程度,更好的解决方案可能是将它们合并为单个表和子类。
class Article < ActiveRecord::Base
has_many :comments
has_many :assigned_comments, -> { where(assigned: true) }
has_many :unassigned_comments, -> { where(assigned: false) }
end
class Comment < ActiveRecord::Base
belongs_to :article
# Common functionality
end
class AssignedComment < Comment
default_scope { where(assigned: true) }
before_save -> { self.assigned = true }
# Functionality specific to AssignedComment
end
class UnassignedComment < Comment
default_scope { where(assigned: false) }
before_save -> { self.assigned = false }
# Functionality specific to UnassignedComment
end
答案 2 :(得分:0)
我知道这可能不是你问题的答案。这是关于您的案例的STI简介。
在处理共享大部分相同功能和数据字段的模型类时,应考虑单表继承。
http://eewang.github.io/blog/2013/03/12/how-and-when-to-use-single-table-inheritance-in-rails/
class Article < ActiveRecord::Base
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :article
scope :assigned, where(type: "AssignedComment")
scope :unassigned, where(type: "UnassignedComment")
end
class AssignedComment < Comment
end
class UnassignedComment < Comment
end
all = @article.comments
assigned = @article.comments.assigned
unassigned = @article.comments.unassigned