Sophie Alpert
Sophie Alpert

Reputation: 143194

has_many/belongs_to association leads to double queries

I have the code

class Magazine < ActiveRecord::Base
  has_many :ads
end

class Ad < ActiveRecord::Base
  belongs_to :magazine
end

I have something like the following in my code (given params[:magazine_name], params[:ad_name]):

mag = Magazine.find_by_name(params[:magazine_name])
@ad = mag.ads.find_by_name(params[:ad_name])

If I now access @ad.magazine, it makes another database query finding by the magazine id, which is stored in @ad. Why isn't ActiveRecord smart enough to realize it's already gotten that from the database and it shouldn't it get it again? (And how do I make it smarter?)

Upvotes: 1

Views: 615

Answers (2)

Zachary Wright
Zachary Wright

Reputation: 24080

You want to do something called "eager loading", where you go ahead and load associations that you know you'll be needing soon. The way to do this is different between Rails 2 and Rails 3.

In rails 3, you use the .includes method:

Ad.includes(:magazine).find_by_name(params[:ad_name])

In rails 2, you use the :include hash:

Ad.find_by_name(params[:ad_name], :include => [:magazine])

Upvotes: 0

nickgrim
nickgrim

Reputation: 5437

The reason it's not smart enough is because ActiveRecord doesn't use the identity map pattern by default. The solution is rumoured to be using :inverse_of on your relationships.

Upvotes: 2

Related Questions