I've been looking at this a bit more, and it raises a concern.
While
results = Author.find :all,
:include => :signings,
:conditions => ['signings.when >= ?', '2007-10-01']
works, it instantiates an AR object for each signing, effectively
pre-loading the signings association for each author. Many times this
is what's wanted
However, since my example is really an analog for a more complex
situtation, what if there are LOTS of signings, and they are fairly
heavy-weight objects. The use case here is that I want to present a
list of 'Authors' filtered by those who actually have a 'signing' to
attend, and then when an author is selected to present his/her
signings for selection.
Is there an easy way to do the search to find all of the 'authors' but
leave instantiating the signings association collection until it's
needed?
I tried (Item is the real name for the Author analog, and Schedules for signing:
Item.find(:all, :joins => ' LEFT OUTER JOIN schedules ON
schedules.item_id', :conditions => ['schedules.begin_date > ?',
Time.now])
But that returns 26520 Item objects while:
Item.find(:all).length => 34
The problem here is that one AR object is being instantiated for each
row returned by the outer join.
I imagine that it's an enhancement request to be able to have my cake
and eat it too, i.e. to be able to 'include' :schedules for purpose of
the where clause, and to maintain identity for the resulting Item
objects, but NOT pre-instantiate the schedules association.
Now I could of course get the expanded list and uniq it, but if I benchmark:
Item.benchmark('join') {Item.find(:all, :joins => ' LEFT OUTER JOIN
schedules ON schedules.item_id', :conditions => ['schedules.begin_date
?', Time.now]).length}
=> 26520
Item.benchmark('include') {Item.find(:all, :include => :schedules,
:conditions => ['schedules.begin_date > ?', Time.now]).length}=> 25
The log shows:
join (2.27320)
include (0.18201)
So the cat's already out of the bag as far as time efficiency.