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

[email protected] wrote:

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


We develop, watch us RoR, in numbers too big to ignore.