I have objects that have comments. As part of a periodic email summary, I want to determine comments for a period, and present the objects in the order of oldest commented object first.
Data:
object_id comment_id
30 40
40 42
32 41
30 43
32 44
Output:
Object #30
- comment 40
- comment 43
Object #40
- comment 42
Object #32
- comment 41
- comment 44
I am using this code to get the data to an intermediate array – I tried to get it all in one swoop using .group_by(&:commentable_id) but the data didn’t come out in correct order.
comments = account.comments.all(
:conditions => ["comments.created_at > ?", 8.hours.ago],
:order => "comments.created_at asc" ).map { |c| [c.commentable_id,c.id] }
=> [ [30,40], [40,42], [32,41], [30,43], [32,44] ]
If I can get that data to transform into the following form, I could just iterate over the array to build the email content…
[ [30,[40,43]], [40,[42]], [32,[41,44]] ]
But I wonder if I’m making this harder than I need to… Any advice?
(I’m using Rails 2.3 and Ruby ree-1.8.7)
You can use a group with an array aggregate to get to the array form that you’re looking for.
Array aggregates are massively db dependent. MySQL’s is GROUP_CONCAT. Postgres’ is ARRAY_AGG. Sqlite doesn’t have one out of the box, but I know you can define custom aggregate functions, so it’s not impossible.
Haven’t actually tried running this code, but here’s something that should point you in the right direction:
I used the naming from the first example, so you’ll need to change ‘object’ to whatever your table is called. Hope it makes sense. Rails probably doesn’t have inbuilt support for parsing an array, so it will probably return a string for comment_array, and you might have to parse it.