0

I am confused by Ruby's ActiveRecord uniq method. I am using it to try to get back an array of complete objects, not just a particular field.

In my Padrino app script, which saves newspaper names and scores as Score objects, the uniq method by attribute on an ActiveRecord Relation is not working, and neither is distinct, with or without SQL syntax. Can anyone explain what is going on?

class Score < ActiveRecord::Base

    def self.from_today
        self.where('created_at > ?', Date.today)
    end
end


scores = Score.from_today
scores.class      
=> Score::ActiveRecord_Relation 

scores.first
=> #<Score id: 123, score: -2.55, source: "Mail", created_at: "2016-08-11 04:29:24", updated_at: "2016-08-11 04:29:24">

scores.map(&:source) 
=> ["Mail", "Guardian", "Telegraph", "Independent", "Express", "Mail"]

scores.uniq(:source).count 
=> 6

scores.distinct(:source).count
=> 6

scores.select('distinct (SOURCE)').count
=> 5    #AHA, it works!

scores.select(:source).distinct
=> #<ActiveRecord::Relation [#<Score id: nil, source: "Telegraph">, #<Score id: nil, source: "Mail">, #<Score id: nil, source: "Independent">, #<Score id: nil, source: "Express">, #<Score id: nil, source: "Guardian">]>

        #oops, no it doesn't
Jonathan_W
  • 638
  • 9
  • 24

1 Answers1

0

In Rails 5 distinct has no parameter. In Rails 4.2 the parameter is only true or false. When true, return distinct records, when false return none distinct records. uniq is in this case only an alias for distinct

So for Rails 4

scores.select(:source).distinct.count is what you want. This restricts distinct to column source

slowjack2k
  • 2,566
  • 1
  • 15
  • 23
  • But it will not return full objects, will it? – Sergio Tulentsev Aug 11 '16 at 06:57
  • `scores.select(:source).distinct` does not return full objects. Only objects with filled source columns. Because you can't say which values you want for the other attributes. For instance the object with the `source` Mail which value should have `created_at`? The value of record 123 or the other? – slowjack2k Aug 11 '16 at 07:00
  • So how do I get back all the Score objects with unique :source attribute? – Jonathan_W Aug 11 '16 at 07:34
  • For your example you want all score objects except the objects with source `Mail`? Or do you want all score objects including the first or last object with source `Mail`? – slowjack2k Aug 11 '16 at 07:38