Some notes on your code:
User.all.where
-> User.where
.
- The moment you write
group_by
you are not using SQL anymore, performance will suffer.
- The line starting with
sum
is very confusing, the indentation make you think it's the continuation of map
but in fact it's part of its inner expression. Indentation should reflect the structure of an expression.
map
+ flatten
-> flat_map
.
|pair, something|
and then pair[0]
. You can de-structure arrays using the syntax |(k, v), something|
.
On a first refactor, I'd write:
@nation_biopsy = User
.where(country: @nation)
.group_by { |u| [u.institute_type, u.biopsy] }
.flat_map do |(institute_type, biopsy), users|
["name" => institute_type, "y" => User.where(id: users.map(&:id)).sum("biopsy")]
end.to_json
On a second refactor, I'd try to make it work with SQL. Something like this:
@nation_biopsy = User
.where(country: @nation)
.group(:institute_type, :biopsy)
.select(:institute_type, "SUM(biopsy) AS biopsy_count")
.flat_map { |group| ["name" => group.institute_type, "y" => group.biopsy_count] }
.to_json
Now, if you want to write something fancy use Arel, it allows you to write it without SQL fragments, which looks kind of cool:
users = User.arel_table
@nation_biopsy = User
.where(users[:country].eq(@nation))
.group(users[:institute_type], users[:biopsy])
.select(users[:institute_type], users[:biopsy].sum.as("biopsy_count"))
.flat_map { ["name" => group.institute_type, "y" => group.biopsy_count] }
.to_json
User
table. Tell us more about your database schema? \$\endgroup\$ – 200_success Dec 12 '15 at 17:11