What is this? From this page you can use the Social Web links to save Ordering Eager-loaded Data to a social bookmarking site, or the E-mail form to send a link via e-mail.

Social Web

E-mail

E-mail It
February 01, 2008

Ordering Eager-loaded Data

Posted in: Ruby on Rails

If you are using Active Record with Ruby on Rails, I’m sure you’re familiar with the :include symbol for the find method. Here’s an example where we have a category structure of Categories -> SubCategories:

@category = Category.find(params[:id], :include => [:sub_categories])

This will find the category with id = params[:id] and will eager load all of the related sub categories. This way we only need to run one query, rather than two. We could also do this

@category = Category.find(params[:id], :include => [:sub_categories, {:sub_categories => :products }])

Now we are going down another level and retrieving all products related to each sub_category. Unfortunately, there is no way to go travel further into your data model with the :includes symbol. If anyone has a good approach, I’m all ears.

The problem I’ve run into is that my Category model has has_many :sub_categories, :order => ‘rank asc’. When I include :sub_categories, Active Record does not recognize my ordering. This caused me quite a few headaches until I came across this in the docs:

” Since the eager loading pulls from multiple tables, you‘ll have to disambiguate any column references in both conditions and orders. So :order => “posts.id DESC” will work while :order => “id DESC” will not. Because eager loading generates the SELECT statement too, the :select option is ignored.” Here’s the link:

So the best approach would be @category = Category.find(params[:id], :include => [:sub_categories, {:sub_categories => :products}], :order => “categories.rank, sub_categories.rank”)

This will order your categories and sub categories. Hopefully someone finds this useful. If you have come up with a better approach, please let me know.


Return to: Ordering Eager-loaded Data