# Eager loading associations with ordering

**URL:** <https://www.ruby-forum.com/t/eager-loading-associations-with-ordering/118379>\
**Category:** Rails\
**Created:** [October 26, 2007, 9:26am UTC](https://www.ruby-forum.com/t/eager-loading-associations-with-ordering/118379 "2007-10-26T09:26:33Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![arvliet](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ee59a6/32.png) [@arvliet](https://www.ruby-forum.com/u/arvliet)\
**Post date:** [October 26, 2007, 9:26am UTC](https://www.ruby-forum.com/t/eager-loading-associations-with-ordering/118379/1 "2007-10-26T09:26:33Z")

</div>

This was a sneaky bug that I managed to track down in my code… I hope  
it helps someone. I first thought this might be a shortcoming or a bug  
in Rails but I’m not really sure where the fault lies: I guess it’s  
just an unexpected or suprising behaviour, or else my misuse of  
ActiveRecord’s magic.

# Problem simplified down to the ubiquitous Project/Task paradigm.

# Let’s use acts\_as\_list for convenience.

class Project \< ActiveRecord::Base  
has\_many :tasks, :order =\> :position

def next\_action  
tasks.first  
end  
end

class Task \< ActiveRecord::Base  
belongs\_to :project  
acts\_as\_list :scope =\> :project\_id  
end

# Let’s create a project with some tasks and move

# the last one to the top, as might happen in normal use:

p = Project.create :name =\> “Halloween costume”  
task\_names = [“paint wings”, “recharge lightsaber”, “get bear slippers”]  
task\_names.each do |t|  
p.tasks \<\< Task.new :name =\> t  
end  
p.tasks.last.move\_to\_top

# Now in our controller, we want to select all projects ordered by name.

# We’ll also want to display the next action… so let’s

# eager load the tasks association:

@projects = Project.find :all, :order =\> :name, :include =\> :tasks

# in the view:

\<% @projects.each do |project| %\>  
\<%= project.next\_action %\>  
\<% end %\>

Surprise! the next action is not the one we moved to the top! What I’m  
understanding is that the find action uses only :order =\> :name, and  
replaces the position ordering which is specified in the model.

Thoughts:

Could Rails handle this more intelligently for us? I had expected that  
it would pile on the :order statements like “ORDER BY project.name,  
task.position” but it doesn’t seem to do that at all.

Or else, should rails put up a warning when something like this occurs  
(when an existing ordering is overwritten)?

To work around this, Instead of the method above, I added a proxy on  
the Project, replacing the next\_action method above:

has\_one :next\_action, :class\_name =\> ‘Task’, :conditions =\> {  
:position =\> 1 }

This seems to work, and I can now include just the next\_action  
association where needed. Problem solved. But, this works because we’re  
no longer using a has\_many association at all. I’m still wondering if  
it’s possible to maintain multiple ordering with has\_many… Any  
thoughts on this?

–Andrew V.

---

<div class="post-metadata">

**Author:** ![arvliet](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ee59a6/32.png) [@arvliet](https://www.ruby-forum.com/u/arvliet)\
**Post date:** [October 26, 2007, 11:49am UTC](https://www.ruby-forum.com/t/eager-loading-associations-with-ordering/118379/2 "2007-10-26T11:49:47Z")

</div>

> Could Rails handle this more intelligently for us? I had expected that  
> it would pile on the :order statements like “ORDER BY project.name,  
> task.position” but it doesn’t seem to do that at all.

You’re correct, it’s ignored. The eager loading code is basically  
hellish enough as it is. Assuming it did work, you might also have  
problems if for whatever reason the associations you were eager  
loading required conflicting orderings (and it might not be  
completely obvious to work out this was the case). I’ve actually got  
a patch (#9640) in trac currently that reimplements :include in such  
a way that a lot of things (including order) work a lot nicer, but  
it’s still a work in progress

> Or else, should rails put up a warning when something like this occurs  
> (when an existing ordering is overwritten)?  
> Quite possibly.

Fred
