views:

76

answers:

2

I have a model (Expense) that contains fields like 'cost'.

I'd like to iterate through all my expenses to find the sum of the cost for all entries belonging to a particular month.

Is there a way to do it in rails directly?

Expense.find(:all, :conditions => .....)

A: 

sum/group_by:

Expense.find(:all, 
             :select => "SUM(cost) as cost_sum, MONTH(date) as month, YEAR(date) as year",
             :group => "MONTH(date), YEAR(date)" )
anshul
This will not work as ActiveRecord ignores all non modelcolumns(in this case any column not present in `expenses` table). You have to `select_extra_columns` gem to return non model columns in the result-set.
KandadaBoggu
Umm... I just tested this and it seems to work just fine in in ruby 1.9.1/ rails 2.3.5. `Expense.find(:all, :select => "SUM(cost) as cost_sum, MONTH(date) as month, YEAR(date) as year",:group => "MONTH(date), YEAR(date)" ).map{ |x| puts "#{x.year}_#{x.month} - #{x.cost_sum}" } `Of course, your solution is more rails-y but just for completeness, this one works too.
anshul
+4  A: 

To get the SUM of costs for the month of a given date:

  # date = any day of the month of intrest
  Expense.sum(:cost, :conditions => {:created_at => 
              (date.beginning_of_month..date.end_of_month)})

To get the sum of costs of all the months:

Expense.sum(:cost, 
    :group => "EXTRACT(YEAR_MONTH FROM created_at)").each do |y_m, cost_sum|
  p "#{y_m}-#{cost_sum}"
end

In the above call, use the conditions option to restrict the result-set to a date range.

KandadaBoggu