35

The docs: http://guides.rubyonrails.org/active_record_querying.html#selecting-specific-fields

Clearly state that:

query = Client.select(:name).distinct
# => Returns unique names

However, when I try that in my controller, I get the following error:

undefined method `distinct' for #<ActiveRecord::Relation:0xb2f6f2cc>

To be clear, I want the distinct names, like ['George', 'Brandon'], not the clients actual records. Is there something that I am missing?

4
  • What version of Rails are you using? Commented Aug 1, 2013 at 21:01
  • ruby 1.9.2p290 (2011-07-09 revision 32553) [i686-linux] Commented Aug 1, 2013 at 21:02
  • 1
    That's your Ruby version, which is actually out of date. You should be using 1.9.3 or better. rails -v will tell you which version of Rails you're using. Commented Aug 1, 2013 at 21:12
  • Another way to select uniq records with Rails you can find here Commented Aug 9, 2017 at 14:38

4 Answers 4

57

Rails 2

If you are still on rails 2 you will need to use:

Client.select('distinct(name)')

Rails 3

If you are on Rails 3 you will need to use:

Client.select(:name).uniq

If you look at the equivalent section of the rails 3 guide you can see the difference between the two versions.

Rails 4+

The .distinct option was added for rails 4 which is what the latest guides refer to.

Client.select(:name).distinct
Sign up to request clarification or add additional context in comments.

3 Comments

This will fetch all records from db on Rails 3.
The guide link explicitly states it will do SELECT DISTINCT name FROM clients. Yes, it will fetch all distinct names but it will not fetch all records.
At least on Rails 7, select + uniq returns all records to filter then on app, while select + distinct uses DISTINCT in query, returning only uniq list to app
16

If you do not want ActiveRecord::Relations returned, just an array of the names as strings, then use:

Client.distinct.pluck(:name)

To get an ordered result set:

Client.order(:name).distinct.pluck(:name)

Comments

15

There are some approaches:

  1. Rails way:

    Model.select(:name).distinct
    
  2. Semi-rails way

    Model.select("DISTINCT ON(models.name) models.*")
    

    The second allows you to select the first record uniqued by name, but in the whole matter, not only names.

Comments

4

This will work for Rails 2 (pretty old rails I know!), 3 and 4.

Client.select('distinct(name)')

This will actually use the SQL select distinct statement

SELECT distinct name FROM clients

2 Comments

this won't always work in the case that you to two select statements : scope = Client.select("distinct name"); scope = scope.select("address"); You can end up with the invalid sql : "select address, distinct name from clients"
Putting () around the column solves that problem. Updated my answer. Thanks :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.