tekina
tekina

Reputation: 572

Activerecord query with group on multiple columns returning a hash with array as a key

I wrote an ActiveRecord query to fetch count of some data after grouping by two columns col_a and col_b

result = Sample.where(through: ['col_a', 'col_b'], status: [1, 5]).where("created_at > ?", 1.month.ago).group(:status, :through).count

This returns:

{[1, "col_a"]=>7, [1, "col_b"]=>7, [5, "col_a"]=>4, [5, "col_b"]=>1}

Now my question is, how do I access the values in this hash?

Doing something like results[1, "col_a"] throws an error (wrong no. of arguments). I know I can do this by writing a loop and extracting the values one by one.

However I want to know if there is a more idiomatic way to access the values, something similar to results[1], maybe?

Upvotes: 1

Views: 1179

Answers (2)

chrismanderson
chrismanderson

Reputation: 4813

Four possible ways (I'm sure there are others):

# fetch one value at a time
results[[1, "col_a"]]
# => 7

# fetch all the values
results.values
# => [7, 7, 4, 1]

# loop through keys and values
results.each do |key, value|
  puts key
  puts value
end 
# => [1, "col_a"], 7....

# convert results into a more usable hash
results.map! { |k,v| { k.join("_") => v } }.reduce({}, :merge)
results['1_col_a']
# => 7

Another heavier option, especially if this is a query you will do often, is to wrap the results into a new Ruby object. Then you can parse and use the results in a more idiomatic way and define an accessor simpler than [1,'col_a'].

class SampleGroupResult
  attr_reader key, value

  def initialize(key, value)
    @key = key
    @value = value
  end 
end

results.map { |k,v| SampleGroupResult.new(k,v) } 

Upvotes: 1

mlovic
mlovic

Reputation: 864

results[[1, "col_a"]]
# => 7

Upvotes: 2

Related Questions