# Caching reverse associations in ActiveRecord

**URL:** <https://www.ruby-forum.com/t/caching-reverse-associations-in-activerecord/127601>\
**Category:** Rails\
**Created:** [January 30, 2008, 6:34pm UTC](https://www.ruby-forum.com/t/caching-reverse-associations-in-activerecord/127601 "2008-01-30T18:34:56Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![patnakajima](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/48db29/32.png) [@patnakajima](https://www.ruby-forum.com/u/patnakajima)\
**Post date:** [January 30, 2008, 6:34pm UTC](https://www.ruby-forum.com/t/caching-reverse-associations-in-activerecord/127601/1 "2008-01-30T18:34:56Z")

</div>

Let’s say we have two models with a plain has\_many/belongs\_to  
relationship.

class Driver  
has\_one :car  
end  
class Car  
belongs\_to :driver  
end

The question is this: Why isn’t the car’s parent driver cached when  
we  
eager load it? So the following snippet (as impractical as it is,  
it’s  
just an example) would just result in one hit (as opposed to  
ActiveRecord’s current behavior, which hits the db each time that  
#driver is called).

@driver = Driver.find(:first, :include =\> :car)  
@driver.car.driver.car.driver.car.driver.car

Is there a reason for the current behavior?

---

<div class="post-metadata">

**Author:** ![patnakajima](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/48db29/32.png) [@patnakajima](https://www.ruby-forum.com/u/patnakajima)\
**Post date:** [February 7, 2008, 8:05pm UTC](https://www.ruby-forum.com/t/caching-reverse-associations-in-activerecord/127601/2 "2008-02-07T20:05:50Z")

</div>

Pat N. wrote:

> Let’s say we have two models with a plain has\_many/belongs\_to  
> relationship.
> 
> class Driver  
> has\_one :car  
> end  
> class Car  
> belongs\_to :driver  
> end
> 
> The question is this: Why isn’t the car’s parent driver cached when  
> we  
> eager load it? So the following snippet (as impractical as it is,  
> it’s  
> just an example) would just result in one hit (as opposed to  
> ActiveRecord’s current behavior, which hits the db each time that  
> #driver is called).
> 
> @driver = Driver.find(:first, :include =\> :car)  
> @driver.car.driver.car.driver.car.driver.car
> 
> Is there a reason for the current behavior?

Yep, you’re correct, this is silly, and a known deficiency in  
ActiveRecord. Usually, this comes up in situations where you are  
calling a method on car from a method in driver. The method in Car in  
turn needs some information about Driver. The quick fix for this is to  
send a reference to Driver to the method in Car instead of having the  
car rely on it’s one #driver method:

class Driver \< ActiveRecord::Base  
has\_one :car  
def some\_driver\_method  
self.car.some\_car\_method(args,self)  
end  
end

class Car \<ActiveRecord::Base  
belongs\_to :driver  
def some\_car\_method(args,dvr=self.driver)  
dvr.some\_attribute  
end  
end

If this seems like a hack, it is. You might also checkout DataMapper  
([http://datamapper.org/](http://datamapper.org/)) which solves this problem, but is not really  
mature enough, IMHO. (see [Antares Trader](http://blog.antarestrader.com/?p=33) for My  
Humble Opinion)

---

<div class="post-metadata">

**Author:** ![patnakajima](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/48db29/32.png) [@patnakajima](https://www.ruby-forum.com/u/patnakajima)\
**Post date:** [February 7, 2008, 10:24pm UTC](https://www.ruby-forum.com/t/caching-reverse-associations-in-activerecord/127601/3 "2008-02-07T22:24:56Z")

</div>

On 7 Feb 2008, at 19:05, Starr T. wrote:

> > end  
> > @driver.car.driver.car.driver.car.driver.car

You could also manaually set the association target. I suppose that in  
general it is non trivial to figure out which association (or even  
associations) is the reverse association (especially with more  
complication associations using conditions etc…).

Fred
