ActiveRecord:属性唯一

时间:2014-11-02 16:59:14

标签: activerecord ruby-on-rails-4

我正在尝试按父ID过滤ActiveRecord_AssociationRelation为唯一。

所以,我喜欢这样的列表:

[#<Message id: 25, posted_by_id: 3, posted_at: "2014-10-30 06:02:47", parent_id: 20, content: "This is a comment", created_at: "2014-10-30 06:02:47", updated_at: "2014-10-30 06:02:47">,
   #<Message id: 23, posted_by_id: 3, posted_at: "2014-10-28 16:11:02", parent_id: 20, content: "This is another comment", created_at: "2014-10-28 16:11:02", updated_at: "2014-10-28 16:11:02">]}

返回:

[#<Message id: 25, posted_by_id: 3, posted_at: "2014-10-30 06:02:47", parent_id: 20, content: "This is a comment", created_at: "2014-10-30 06:02:47", updated_at: "2014-10-30 06:02:47">]

我尝试过各种技巧,包括:

@messages.uniq(&:parent_id) # returns the same list (with duplicate parent_ids)

@messages.select(:parent_id).distinct # returns [#<Message id: nil, parent_id: 20>]

uniq_by已从Rails 4.1中删除。

2 个答案:

答案 0 :(得分:4)

你试过吗

group(:parent_id)

这听起来像是你所追求的。这确实返回给定parent_id的第一个条目。如果您想要最后一个条目,则必须在子查询中重新排序结果,然后使用该组。

答案 1 :(得分:3)

对于Rails 3.2&amp; Postgresql,Foo.group(:bar)适用于简单查询,但如果我在那里有任何where子句,则会给我一个错误,例如

 irb> Message.where(receiver_id: 434).group(:sender_id)
 => PG::GroupingError: ERROR:  column "messages.id" must appear in the
    GROUP BY clause or be used in an aggregate function

我最终指定要选择的SQL'DISTINCT ON'子句。在Message类中,我有以下范围:

 scope :latest_from_each_sender, -> { order("sender_id ASC, created_at DESC").select('DISTINCT ON ("sender_id") *') }

用法:

 irb> Message.where(receiver_id: 434).latest_from_each_sender