def self.group_by_month(events)
event_hash = {}
events.each do |event|
start = event.start_date.to_s(:month_year)
event_hash[start] ||= []
event_hash[start] << event
end
event_hash.sort {|a,b| Time.parse(a[0]) <=> Time.parse(b[0]) }
end
Refactorings
No refactoring yet !
steved
September 23, 2010, September 23, 2010 17:23, permalink
Rails adds group_by to the Array returned by all.
# assume you have added :month_year to DateTime::DATE_FORMATS
events_by_month_year = events.group_by { |e| e.start_date.to_s(:month_year) }
Luke
September 23, 2010, September 23, 2010 20:03, permalink
Your code is much more succinct than mine, so it's certainly an improvement, but I'm still wondering if there's a solution that has the DB do most of the work.
steved
September 25, 2010, September 25, 2010 15:40, permalink
Event.all({
:select => "*, concat(year(start_date), '-', month(start_date)) as month",
:group => "month",
:order => "month",
})
Luke
September 27, 2010, September 27, 2010 05:15, permalink
Very nice. This is exactly what I was looking for. For SQLITE the syntax is:
Event.all(:select => "*, strftime('%Y%m', start_date) as month", :order => "month", :group => "month")
Ideally it would return an array of arrays. Each of the sub-arrays being the contents of a given month. As it stands I get one event per month. So, I'll probably just remove the group clause and detect the month boundry as I iterate over the array.
Thanks again Steve!
Given an event with the following attributes:
name:string
start_date:datetime
I want to:
1) return events, grouped by the month/year of the start date.
2) ensure the events for each returned month/year are ordered by start_date
Is this possible using SQL ? Here's the ruby code I use to accomplish this.
I'm using rails 2.3.8, so I'd prefer answers that work for that. I'd be interested in seeing some rails 3 solutions too.