Reputation: 182
before I start I just want to tell that I tried some aproaches from similar topics but they don't work well with my case.
I have orders that I am grouping by days (using group_by(&:created_at) method). Now I want to sum "total" field from orders that are on particular days. It should look something like that: 21 May 2015 Total: 215 (order1 with total = 200 and order2 with total = 15) 22 May 2015 Total: 0 23 May 2015 Total: 321
I tried something like this
orders.to_a.map { |h| h[:total] }.sum
orders.to_a.inject { |sum, h| sum += h[:total] }
but it prints me only totals from each order (not daily sum).
I am fetching data from database (postgres) like this:
@orders = current_user.orders.where(created_at: Time.now.beginning_of_month.. Time.now).group_by(&:created_at)
And I'm getting something like this as a result:
{Sat, 06 Jun 2015 13:06:08 CEST +02:00=>
[#<Order id: 19, total:10],
[#<Order id: 20, total:12],
Fri, 05 Jun 2015 15:42:24 CEST +02:00=>
[#<Order id: 19, total:10],
[#<Order id: 20, total:12]}
@pauloancheta Using your solution and having view like this (HAML)
#subtotal
- @orders.each do |day,orders|
.col-md-4
%h2
= day.strftime("%Y %m %d")
= link_to '', monthly_summary_path(date: day), class: "btn btn-info btn-small glyphicon glyphicon-zoom-in"
%p= "sum: #{orders.map(&:total).sum}"
When I have two orders in one day i get two separate columns instead of 1 with sum.
Upvotes: 1
Views: 2151
Reputation: 434745
First of all, created_at
is a timestamp not a date so you're not grouping by dates at all, you're grouping by date and time of day. This is why you'll get multiple results for some dates.
Secondly, you can get the database to do all the work by using a GROUP BY on the date and then summing the total
within each group:
current_user.orders
.where(created_at: Time.now.beginning_of_month .. Time.now)
.group('created_at::date')
.sum(:total)
That will give you a Hash like this:
{ date_object => sum_for_that_date, ... }
Upvotes: 3
Reputation: 359
I tried this with my console and it worked. Hope it would work for you as well. orders.map(&:total).sum
Order.where
already returns an array so I think there is no need for a .to_a
method.
Upvotes: 1