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]
, p开发者_Go百科arams[: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?)
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.
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])
精彩评论