user3281384
user3281384

Reputation: 531

ActiveRecord: Unique by attribute

I am trying to filter ActiveRecord_AssociationRelations to be unique by parent id.

So, I'd like a list like this:

[#<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">]}

to return this:

[#<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">]

I've tried various techniques including:

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

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

and uniq_by has been removed from Rails 4.1.

Upvotes: 3

Views: 4705

Answers (2)

cedricdlb
cedricdlb

Reputation: 759

For me in Rails 3.2 & Postgresql, Foo.group(:bar) works on simple queries but gives me an error if I have any where clauses on there, for instance

 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

I ended up specifying an SQL 'DISTINCT ON' clause to select. In a Message class I have the following scope:

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

Usage:

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

Upvotes: 3

Albin
Albin

Reputation: 3012

Have you tried

group(:parent_id)

It sounds to me like that is what you are after. This does return the first entry with the given parent_id. If you want the last entry you will have to reorder the result in a subquery and then use the group.

Upvotes: 4

Related Questions