Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby / Rails - How to aggregate a Query Results in an Array?

I have a large data set that I want to clean up for the user. The data set from the DB looks something like this:

ID | project_id | thread_id | action_type |description
 1 | 10         | 30        |  comment    | yada yada yada yada yada
 1 | 10         | 30        |  comment    | xxx
 1 | 10         | 30        |  comment    | yada 313133
 1 | 10         | 33        |  comment    | fdsdfsdfsdfsdfs
 1 | 10         | 33        |  comment    | yada yada yada yada yada
 1 | 10         |           | attachment  | fddgaasddsadasdsadsa
 1 | 10         |           | attachment  | xcvcvxcvxcvxxcvcvxxcv

Right now, when I output the above in my view its in the very same order as above, problem is it is very repetitive. For example, for project_id 10 & thread_id 30 you see:

10 - 30 - yada yada yada yada yada
10 - 30 - xxxxx
10 - 30 - yada yada yada yada yada

What I would like to learn how to do in ruby, is some how create an array and aggreate descriptions under a project_id and thread_id, so instead the output is:

10 - 30
 - yada yada yada yada yada
 - xxxxx
 - yada yada yada yada yada

Any advice on where to get started? This requirement is new for me so I would appreciate your thoughts on what you're thinking the best way to solve this is.Hopefully this can be done in ruby and not sql, as the activity feed is likely going to grow in event types and complexity.

Thanks

like image 829
AnApprentice Avatar asked Feb 11 '11 23:02

AnApprentice


1 Answers

Use group_by http://apidock.com/rails/Enumerable/group_by in Ruby or right in SQL. In Ruby:

sets = DataSet.all.group_by{ |data| [data.project_id, "-", data.thread_id].join(" ") }

Then you'll get Hash like that:

{ "10 - 30" => [#DataSet1, #DataSet2 ...], "10 - 33" => [#DataSet7, #DataSet11 ...]

Which you can parse in view:

<% sets.each do |range, datas| %>
  <p><%= range %>:</p>
  <% datas.each do |data| %>
    <p><%= data.description %></p>
  <% end %>
<% end %>

UPD for each_with_index

<% sets.each_with_index do |datas, index| %>
  <p><%= datas[0] %>:</p>
  <% datas[1].each do |data| %>
    <p><%= data.description %></p>
    # some stuff with *last*
    <%= "This is the last one" if data == datas[1].last %> 
  <% end %>
<% end %>
like image 186
fl00r Avatar answered Oct 12 '22 23:10

fl00r