如何"合并"两个`has_many`模型关联的结果?

时间:2014-06-26 23:53:06

标签: ruby-on-rails ruby activerecord ruby-on-rails-4 associations

我正在使用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这两个数据。

我该怎么做?有一些常见的做法?返回数据和数据库查询怎么样?

3 个答案:

答案 0 :(得分:1)

如果AssignedCommentUnassignedComment具有相同的属性且状态assigned可以更改为unassigned,反之,为什么不添加和归因is_signedComment并执行以下操作:

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

但这有几个缺点:

  1. 它始终将所有assigned_commentsunassigned_comments加载并初始化到内存中。

  2. 它没有任何ActiveRecord::Relation方便的方法

  3. 根据AssignedCommentUnassignedComment列的相似程度,更好的解决方案可能是将它们合并为单个表和子类。

    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