Two-way eager loading?

My problem is that I have two classes where the eager loading isn't working as well as I would hope...

Here are my two classes:

class Daynote < ActiveRecord::Base   belongs_to :userplace

class Userplace < ActiveRecord::Base     has_many :daynote, :dependent => true

When I show my userplaces, I want to get the associated daynotes with them, so I am doing:

    @userplace = Userplace.find(params[:id],:include => :daynote)

What I'm seeing is that @userplace.daynote uses the array of objects from the eager load. That's what I want, since it cuts out a lot of queries. But then if I pass the daynote object to another function or partial, and then use daynote.userplace (the inverse), it has to do a query to look up the userplace, again. I would think I've already loaded that association, so it would use the cached version, but it doesn't.

Now, if I switch the load to:

    @userplace = Userplace.find(params[:id],:include => {:daynote=>:userplace))

then it works, but that's an ugly hack since now it includes the userplace columns twice in the SQL. OTOH, it saves a lot of query time.

Any ideas? It's very possible I'm missing something fundamental here but I'm pretty frustrated.

Thanks, Smackfu

Smackfu@gmail.com wrote:

My problem is that I have two classes where the eager loading isn't working as well as I would hope...

Here are my two classes:

class Daynote < ActiveRecord::Base   belongs_to :userplace

class Userplace < ActiveRecord::Base     has_many :daynote, :dependent => true

When I show my userplaces, I want to get the associated daynotes with them, so I am doing:

    @userplace = Userplace.find(params[:id],:include => :daynote)

What I'm seeing is that @userplace.daynote uses the array of objects from the eager load. That's what I want, since it cuts out a lot of queries. But then if I pass the daynote object to another function or partial, and then use daynote.userplace (the inverse), it has to do a query to look up the userplace, again. I would think I've already loaded that association, so it would use the cached version, but it doesn't.

Yes, at present eager loading does not set the back-link to the parent object if a reciprocal belongs_to exists in the eagerly-loaded model. To implement this the construct_association method in class JoinDependency would have to be modified to first find such a reciprocal association, and then set this to the parent object.

Until then, you'll have to manually fix-up your back pointers, perhaps in an after_find method:

class Userplace < ActiveRecord::Base    def after_find      daynotes.each { |dn| dn.userplace = self } if daynotes.loaded?    end end