2

I have Event model with following attributes (I quoted only problem related attributes), this model is filled periodically by API call, calling external service (Google Calendar):

colorid: number # (0-11)
event_start: datetime
event_end: datetime

I need to count duration of grouped events, grouped by colorid. I have Event instance method to calculate single event duration:

def event_duration
  ((event_end.to_datetime - event_start.to_datetime) * 24 * 60 ).to_i
end

Now, I need to do something like this:

event =  Event.group(:colorid).sum(event_duration)

But this doesnot work for me, as long as I get error that event_duration column doesnot exists. My idea is to add one more attribute to Event model "event_duration", and count and update this attribute during Event record creation, in this case I would have column called "event_duration", and I might be ale to use sum on this attribute. But I am not sure this is good and "system solution", as long as I would like to have model data reflecting "raw" received data from API call, and do all math and statistics on the top of model data.

David Lister
  • 171
  • 2
  • 15

1 Answers1

1

event_duration is instance method (not column name). error was raised because Event.sum only calculates the sum of certain column

on your case, I think it would be easier to use enumerable methods

duration_by_color_id = {}
grouped_events = Event.all.group_by(&:colorid)
grouped_events.each do |colorid, events|
  duration_by_color_id[colorid] = events.collect(&:event_duration).sum
end

Source :

byakugie
  • 643
  • 3
  • 14
  • Thanx a lot, it works auto-magically. Problem is, I am Rails & Ruby beginner and I do not understand this code, event it is just a few lines. I have to check especially that "&:something" magic, and why is used "group_by" and not just "group". – David Lister Oct 11 '15 at 18:33
  • @DavidLister : please check this out : [ampersand colon shorcut](http://stackoverflow.com/questions/1961030/ruby-ampersand-colon-shortcut) – byakugie Oct 13 '15 at 02:23
  • Thanx for reply, I spent some time with study. Let me summarize it if I got it correctly: `duration_by_color_id = {}` Initialize new hash `grouped_events = Event.all.group_by(&:colorid)` Get multidim. array with all events, which are grouped by colorid DB column, because this block is executed for each object and i just call colorid, which gives back value of row. `grouped_events.each do |colorid, events|` Start iterate array. For each colorid key, i have array of events. `duration_by_color_id[colorid] = events.collect(&:event_duration).sum` Gives me array with sum values for each object. – David Lister Oct 14 '15 at 00:20