Forum: Ruby on Rails Issue w/ Eager 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.
4af2441c63e47c4eb0c4b9f6d92ff5e5?d=identicon&s=25 Paul Taylor (ptaylor)
on 2007-06-12 17:14
Hi,

I have a rails app that uses these models:

class CoreRouter < ActiveRecord::Base
  has_many :ports
end

class Port < ActiveRecord::Base
  belongs_to :core_router
  has_many :addresses
end

class Address < ActiveRecord::Base
  belongs_to :port
end

I have one main list page that shows all CoreRouters, the associated
ports and the associated addresses.  The problem is that I now have over
400 addresses and I'm seeing over 400 queries when I generate this page,
taking about 10 seconds to load.  I thought an answer may be Eager
Loading:

@core_routers = CoreRouter.find(:all, :include => [ :ports, :addresses
])

But that fails:

ActiveRecord::ConfigurationError (Association named 'addresses' was not
found; perhaps you misspelled it?):

I'm assuming this is because the CoreRouter class doesn't have a direct
association with the Address class.

How can I get it to eagerly load the addresses that are associated with
the ports?
2f9a03aa0fcfe945229cb6126eda2cb2?d=identicon&s=25 Philip Hallstrom (Guest)
on 2007-06-12 18:29
(Received via mailing list)
>  has_many :addresses
> Loading:
> association with the Address class.
>
> How can I get it to eagerly load the addresses that are associated with
> the ports?

@core_routers = CoreRouter.find(:all,
:include => {:ports => :addresses})

(it's either that or...)

:include => :ports => :addresses)

I can never remember as well I've never actually done it :)
Ef3aa7f7e577ea8cd620462724ddf73b?d=identicon&s=25 Rob Biedenharn (Guest)
on 2007-06-12 19:21
(Received via mailing list)
On Jun 12, 2007, at 12:41 PM, Philip Hallstrom wrote:
>>  has_many :addresses
>> page,
>> was not
> @core_routers = CoreRouter.find(:all,
> :include => {:ports => :addresses})
>
> (it's either that or...)

Yeah, it's that.

and if you need to include a :conditions option when you
have :include's, you need to indicate the table such as
:conditions => [ 'core_routers.installed_on < ? AND ports.in_use = ?',
                  1.year.ago.beginning_of_day.to_s(:db), true ]

-Rob

Rob Biedenharn    http://agileconsultingllc.com
Rob@AgileConsultingLLC.com
4af2441c63e47c4eb0c4b9f6d92ff5e5?d=identicon&s=25 Paul Taylor (ptaylor)
on 2007-06-12 20:16
Philip Hallstrom wrote:
>
> @core_routers = CoreRouter.find(:all,
> :include => {:ports => :addresses})
>

That worked great... Dropped my DB time down from about 2 seconds to
less than .5 seconds...
4af2441c63e47c4eb0c4b9f6d92ff5e5?d=identicon&s=25 Paul Taylor (ptaylor)
on 2007-06-12 20:18
Rob Biedenharn wrote:
>
> and if you need to include a :conditions option when you
> have :include's, you need to indicate the table such as
> :conditions => [ 'core_routers.installed_on < ? AND ports.in_use = ?',
>                   1.year.ago.beginning_of_day.to_s(:db), true ]
>

Thanks Rob - I don't need this yet, but might!
This topic is locked and can not be replied to.