May 12

Rails in practice - Group records by condition

Often, when it comes to views I have to group records and present it to the user grouped by some condition. For example, I would like to list all news articles grouped by year.

To accomplish this, I find it easiest that records are grouped in a hash, key should be year when article is published and value would be array of objects matching published on these year.

Before, I used custom function that would walk throught all elements of array calling custom block for each member and creating new hash with result value of the block as key and array of elements as value.

Today I discover classify method in Set class that would do just what I need (thanks to Cookbook for that).

So, the code to group all news articles by year published is:

@groups = NewsArticle.find(:all).to_set.classify {
  |article| article.published_on.year}

and view would be something like these:

<%@groups.each do |year, articles|%>
  <h1><%=year%></h1>
  <%=articles.collect {|a| \"<p>a.name</p>\"}.join%>
<%end%>

Short and sweet. Same method can be used to group anything, names by first letter, products by price range, etc.