By Ewout Van Troostenberghe, 10-forward

Ewout presented two libraries he has written to simplify complex queries and reporting (subtotals, grouping, etc) in a Rails application. While ReportKit & FilterKit surely deserve a visit on their own, most of the interest of the talk was for me the introduction to Arel (Active Relation), a review/rewrite of Active Record in Rails 3.0, on which both libraries are based. While being the new Rails API, what make the specificities of Arel was not so simple to find, so I did my homework after the talk, as Ewout has more than roused my curiosity.

Shortly said, Arel is a new Query API, based on chained methods, each one returning a query object, that is not executed (and converted to an array) until you iterate through the data. During the whole talk, I had a "familiar" impression that I could not rid of, nor specify. An example being better than a long description, here is one, by Arel author, Nick Kallen himself:

User.order('users.id DESC').limit(20).includes(:items)

Another view on Arel is that what where: options in a hash given to a method are now real method themselves that you can easily chain. It allows you to create complex queries (with associations, projections or others) quite easily, in a very readable format. The method provided by Arel are the following:

  • where (:conditions)
  • having (:conditions)
  • select
  • group
  • order
  • limit
  • offset
  • joins
  • includes (:include)
  • lock
  • readonly
  • from

So you could write something like:

User.where('active' => true).order("created_at DESC")

To select all active users by decreasing creation date. My familiarity most probably comes from Hibernate (one of java most used ORM) Critera API, which equivalent would be something like:

sess.createCritera.for(User.class).add(Restrictions.eq("active",true).addOrder(Order.desc("created_at")).list();

When you set apart the languages differences (and java obvious verbosity in this case), the idea behind is quite similar (Criteria also represents the Query, and are not executed before the "list" call). Having used it in very large project, I can assert that a Query API is something you want in your language/ORM of choice, and I'm glad to see it in Rails 3.

For those willing to investigate, here are the resources I found the most useful:

A big thanks to Ewout for pointing me in Arel direction. I will surely need it in my future projects.