Carpela
Carpela

Reputation: 2195

Count by group and subgroup

I want to generate some stats regarding some data I have in a model

I want to create stats according to an association and a status column.

i.e.

Model.group(:association_id).group(:status).count

to get an outcome like

[{ association_id1 => { status1 => X1, status2 => y1 } },
 { association_id2 => { status1 => x2, status2 => y2 } }...etc

Not really bothered whether it comes out in as an array or hash, just need the numbers to come out consistently. Is there a 'rails' way to do this or a handy gem?

Upvotes: 0

Views: 315

Answers (2)

Carpela
Carpela

Reputation: 2195

Ok. Worked out something a little better, though happy to take advice on how to clean this up.

group_counts = Model.group(["association_id","status"]).count

This returns something like:

=> {[nil, "status1"]=>2,
[ass_id1, "status1"]=>58,
[ass_id2, "status7"]=>1,
[ass_id2, "status3"]=>71 ...etc

Which, while it contains the data, is a pig to work with.

stats = group_counts.group_by{|k,v| k[0]}.map{|k,v| {k => v.map{|x| {x[0][1] => x[1] }}.inject(:merge) }}

Gives me something a little friendlier

=> [{
 nil => {
  "status1" => 10,
  "status2" => 23},
 "ass_id1" => {
  "status1" => 7,
  "status2" => 23
}...etc]

Hope that helps somebody.

Upvotes: 1

Carpela
Carpela

Reputation: 2195

This is pretty ugly, inefficient and there must be a better way to do it, but...

Model.pluck(:association_id).uniq.map{ |ass| { 
  name:(ass.blank? ? nil : Association.find(ass).name), data: 
    Model.where(association_id:ass).group(:status).count 
} }

Gives what I need. Obviously if you didn't need name the first term would be a little simpler.

i.e.

 Model.pluck(:association_id).uniq.map{ |ass| { 
   id:ass, data:Model.where(association_id:ass).group(:status).count 
 } }

Upvotes: 0

Related Questions