Graham Slick
Graham Slick

Reputation: 6870

Rails 5 - Query records with a uniq attribute

I'm using Rails 5 and Postgresql. This question has been answered for previous versions of Rails (including Rails 4, using distinct, uniq, etc, but none of it worked for me with Rails 5 since they've been depreciated).

I have a Upload model, which has a uuid attribute. I want to fetch records having a different uuid without using uniq from enumerables.

Here is my original query:

Upload.includes(:user, product: [:catalog]).where(file_type: "product_attachment", product_id: nil, user_id: current_user.id))

I get errors when adding distinct or select (and it seems like those methods are often used to return only one attribut from the model while I need the whole object here).

Any idea on how to achieve this in Rails 5 ?

Edit with sample data:

Uploads:

id: 1 
uuid: 8e8fece82b6b1368ab6f21852c625e85718d210e

id: 2
uuid: 842e7650b4bba97f097d9cf57f47d8160086b7cd

id: 3
uuid: 8e8fece82b6b1368ab6f21852c625e85718d210e

Uploads 1 and 3 have the same uuid, so the expected result would only contain the uploads with id 1 and 2 (which have a distinct uuid).

Upvotes: 1

Views: 560

Answers (2)

Vijay Agrawal
Vijay Agrawal

Reputation: 1683

Assuming you want Upload with minimum id for every duplicate group of uuid,

Upload.includes(:user, product: [:catalog]).where(file_type: "product_attachment", product_id: nil, user_id: current_user.id)).
       where(id: Upload.group(:uuid).select("min(id)"))

To break it down, this where clause filters all the Upload with duplicate uuid except the one with min id

where(id: Upload.group(:uuid).select("min(id)"))

Upvotes: 1

Ashish Jambhulkar
Ashish Jambhulkar

Reputation: 1504

You can use group; it gives you all distinct records without using uniq:

ABC.group(:uuid)

Upvotes: 0

Related Questions