Some use cases for find(:all, :include => ...) can stress memory footprint.
Motivation: My example use case
I have an application which presents a list of different types of items, each of which has multiple timed occurrences (schedules). For example, items might represent appearances by a particular performing artist, or author, and the schedules have information about where, when, and other information. There may be MANY schedules, some of which have already occurred.
So item has_many :schedules
and schedule belongs_to :item
In order to present a list of items, the application requirement is to find all items which have at least one occurrence on or after a cutoff date.
In discussion on rails-talk the following query was suggested:
Item.find(:all,
:include => :schedules,
:conditions => ['schedules.time >= ?', cutoff_time]
)
This works, however since :include eagerly builds the association collection for each item, it instantiates an active record object for each schedule after the cutoff.
The above call generates
select ... from item left outer join of schedules to items where schedules.time >= ...
The result of this query produces a row for each combination of item and future schedule for that item, which AR coalesces using a hash to detect and reuse already instantiated, adding associated schedules to the proper item for each row.
The patch adds an option to ActiveRecord::Base#find so that one can code:
Item.find(:all,
:include => :schedules,
:lazy_associations => true,
:conditions => ['schedules.time >= ?', cutoff_time]
)
This does everything as before except for creating the association collection at the time of the find.
The patch, excluding comments and tests is 5 lines.
Note that this proposal is a simpler approach to (some of) the issues raised by http://dev.rubyonrails.org/ticket/9640