Forum: Ruby on Rails Lazy Loading?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Jason F. (Guest)
on 2005-12-21 03:52
I'm having problems with what seems to be lazy loading behavior in Ruby
on Rails.  I have two objects in a parent-child relationship such as:

  class Order < ActiveRecord::Base
    has_many :items, :dependent => true
  end
  class Item < ActiveRecord::Base
    belongs_to :order
  end

I put an instance of the Order object into the session using:

  session[:order] = Order.new

I then extract the object in the controller and set it equal to the
instance variable @order so that it is accessible in my view.

  def myaction
    @order = session[:order]
  end

Now, my problem is that, in the view, the items array in @order is nil
UNLESS I access the items array in the controller, e.g.,

  def myaction
    @order = session[:order]
    logger.debug(@order.items)
  end

This seems to me that Rails is loading the items array in a lazy fashion
(which is great and expected), however, for some reason it *only* does
this in the controller.  That is, if I access the items array in the
view, it doesn't trigger the loading of the array.  Am I doing something
wrong here?  Is there a way to control the lazy loading behavior of
Rails?  Help!
Ed C. (Guest)
on 2005-12-21 06:44
(Received via mailing list)
Jason,

It's been my experience that if you're saving models into a session
(as opposed to just the models' unique id), then you can't lazy-load
them.

In your application.rb file, try adding model :order

See the Rails wiki article [1] for more info on session handling.

[1] http://wiki.rubyonrails.com/rails/pages/HowtoWorkW...
Jason F. (Guest)
on 2005-12-21 15:44
Thanks for the response, Ed...

I did have the model :order set in the application.rb file as well as
model :line, however, it still did not work.  Lazy-loading of the items
did work in the controller, when the object was retrieved from the
session, just not in the view.

I've changed my approach to just store the id of the order in the
session and then load the order in my controller with the extra :include
=> :items parameter, e.g.,

  @order = Order.find(:all, conditions => "id = #{session[:order_id]}",
:include => items)

I found out that this extra parameter will tell Rails to load the items
array when the order object is loaded instead of loading the items in a
lazy fashion.  I then use the @order object in my view and it works
fine.

I would, however, still like to understand the details of how Rails does
lazy loading.  So if anyone out there knows, please drop me a line.
Thanks!
Rick O. (Guest)
on 2005-12-21 15:48
(Received via mailing list)
>   @order = Order.find(:all, conditions => "id = #{session[:order_id]}",
> :include => items)

Whoa, hold on there cowboy.  Coding like that can get you an sql
injection attack.  (Unlikely with a session value, but you don't want
to get in the habit).

@order = Order.find(:all, :conditions => ['id = ?',
session[:order_id]], :include => :items)

--
rick
http://techno-weenie.net
This topic is locked and can not be replied to.