views:

58

answers:

0

I'm working on a timesheet system (thrilling, I know) and am having difficulty using ActiveRecord to total the time spent working on particular projects on each day.

I have a TimeBooking model:

t.references :assignment,  :null => false # (Combination of employee and project)
t.date       :date,        :null => false
t.integer    :duration,    :null => false # Duration in minutes
t.string     :description, :null => false, :default => ''

On any given day an employee might work on the same assignment several times, in which case there will be several TimeBooking entries for the same assignment and date.

On the employee's timesheet view I want to present the total work for the day, doing as much of the hard work in the database as possible. My code reads:

TimeBooking.sum( :duration,
                 :conditions => { :assignment_id => [... array of assignment IDs ...] ),
                                  :date => (@[email protected]_of_month) },
                 :group => "assignment_id, date")

This generates a sensible looking SQL statement in the debug log (I'm using PostgreSQL):

SELECT sum("time_bookings".duration) AS sum_duration,
       assignment_id,
       date AS assignment_id_date
FROM "time_bookings"
WHERE (     "time_bookings"."assignment_id" IN (60,70)
        AND "time_bookings"."date" BETWEEN '2010-04-01' AND '2010-04-30' )
GROUP BY assignment_id, date 

If i run this in PostgreSQL directly I get the table of results I expect:

sum_duration;assignment_id;assignment_id_date
50;70;"2010-04-12"
100;60;"2010-04-04"
50;60;"2010-04-14"
25;70;"2010-04-14"

However the results from the ActiveRecord statement (dumped via to_yaml) are different:

--- !map:ActiveSupport::OrderedHash 
"2010-04-12": 50
"2010-04-04": 100
"2010-04-14": 25

The assignment_id has disappeared entirely and I've only got one of the two time totals for the 14th. If I run the query from the debug log via find_by_sql I can get the results I expect (all wrapped in TimeBooking objects), so it appears to be a problem with how TimeBooking.sum() is converting the database results back into AR objects. Any pointers on what I'm doing wrong (or, less likely, what the bug in AR (2.3.4) is) would be helpful, as I'd rather not rely on hardcoded SQL.