www.flickr.com
|
Thursday, July 20, 2006
Rails realities part 16 (Finders and second order relations)
I recently needed to run a finder query and have the results sorted by a property on a second order relation. What the heck does that mean? This:
The documentation in rails shows you how to load a single related object but not how to load related objects of THAT object. A google of "rails find sort related" returned http://rails.techno-weenie.net/question/2006/1/27/dynamic_finders_sorting_by_a_related_object which is almost there.
The answer to the above problem is:
The difference being that the :include parameter is a hash to a hash instead of just pointing to a single association.
Many thanks to technoweenie in #caboose. After getting the solution from it does appear somewhat obvious and the docs didn't appear to have anything, but upon further review there is something that shows an example of chaining includes on a finder query. In the "Table Aliasing" section of the ActiveRecord::Associations::ClassMethods API docs.
For extra credit technoweenie also pointed out that you could do the joins manually like so:
Note that you can also include more than one first order relation as follows:
And though I haven't tried it I suspect that from there you could include each of those relations' related objects in the same manner as described earlier.
Be warned that the queries produced are going to get ugly, but happy relation chaining :-)
- Foo has_one bar
- Bar has_one baz
- Baz has a property 'name'
"Find me all Foos and sort the result by the 'name' property on the Baz object"
The documentation in rails shows you how to load a single related object but not how to load related objects of THAT object. A google of "rails find sort related" returned http://rails.techno-weenie.net/question/2006/1/27/dynamic_finders_sorting_by_a_related_object which is almost there.
The answer to the above problem is:
Foo.find(:all, :include => { :bar => :baz }, :order => 'baz.name')
The difference being that the :include parameter is a hash to a hash instead of just pointing to a single association.
Many thanks to technoweenie in #caboose. After getting the solution from it does appear somewhat obvious and the docs didn't appear to have anything, but upon further review there is something that shows an example of chaining includes on a finder query. In the "Table Aliasing" section of the ActiveRecord::Associations::ClassMethods API docs.
For extra credit technoweenie also pointed out that you could do the joins manually like so:
find :all, :joins => 'inner join bars on bars_id = bars.id inner join bazs on bazs.id = bars.bazs_id'
Note that you can also include more than one first order relation as follows:
Foo.find(:all, :include => [:bar, :biz], :order => 'biz.name')
And though I haven't tried it I suspect that from there you could include each of those relations' related objects in the same manner as described earlier.
Be warned that the queries produced are going to get ugly, but happy relation chaining :-)
Post a Comment