Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #9923 (closed enhancement: duplicate)

Opened 9 months ago

Last modified 8 months ago

[PATCH] Add option to lazily instantiate included associations

Reported by: RubyRedRick Assigned to: core
Priority: normal Milestone: 2.x
Component: ActiveRecord Version: edge
Severity: normal Keywords:
Cc:

Description

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

Attachments

lazyattr.diff (5.6 kB) - added by RubyRedRick on 10/18/07 17:21:12.
Patch to add :lazy_attributes option to ActiveRecord::Base

Change History

10/18/07 17:21:12 changed by RubyRedRick

  • attachment lazyattr.diff added.

Patch to add :lazy_attributes option to ActiveRecord::Base

10/28/07 17:23:20 changed by RubyRedRick

  • status changed from new to closed.
  • resolution set to duplicate.

This has been superseded by http://dev.rubyonrails.org/ticket/10012 which accomplishes the same intent (and more) with much better API syntax.