# Unequal Object Identities in Rails

**URL:** <https://www.ruby-forum.com/t/unequal-object-identities-in-rails/111109>\
**Category:** Rails\
**Created:** [August 2, 2007, 7:13pm UTC](https://www.ruby-forum.com/t/unequal-object-identities-in-rails/111109 "2007-08-02T19:13:40Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jfoxny](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a6a055/32.png) [@jfoxny](https://www.ruby-forum.com/u/jfoxny)\
**Post date:** [August 2, 2007, 7:13pm UTC](https://www.ruby-forum.com/t/unequal-object-identities-in-rails/111109/1 "2007-08-02T19:13:40Z")

</div>

My question is best illustrated by an example. Let’s say we have two  
simple classes, Order and LineItem defined as follows.

class Order \< ActiveRecord::Base  
has\_many :line\_items  
end  
class LineItem \< ActiveRecord::Base  
belongs\_to :order  
end

We then open up script/console and load our first order and compare the  
object IDs of the order that is returned and the order on the first line  
item. These values never seem to be the same no matter how I obtain the  
line item.

> > o = Order.find(:first)  
> > l = o.line\_items.first  
> > o.object\_id == l.order.object\_id  
> > =\> false

The IDs are also not the same if you do this…

> > o = Order.find(:first, :include =\> :line\_items)  
> > l = o.line\_items.first  
> > o.object\_id == l.order.object\_id  
> > =\> false

Or this…

> > o = Order.find(:first, :include =\> :line\_items)  
> > l = o.line\_items.select{ |l| true }.first  
> > o.object\_id == l.order.object\_id  
> > =\> false

I noticed this because I have a method in my LineItem class that  
attempts to update a value on it’s parent Order object like so:

def line\_total=(value)  
self.line\_total = value  
self.order.total += self.line\_total  
end

The parent Order’s value is never updated because it is a different  
object instance than the Order that the line item has a reference to.  
Am I doing something wrong or is this always the case in Rails? Any  
help would be much appreciated.

Regards,  
Jason

---

<div class="post-metadata">

**Author:** ![jfoxny](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a6a055/32.png) [@jfoxny](https://www.ruby-forum.com/u/jfoxny)\
**Post date:** [August 2, 2007, 7:18pm UTC](https://www.ruby-forum.com/t/unequal-object-identities-in-rails/111109/2 "2007-08-02T19:18:50Z")

</div>

On 8/2/07, Jason F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> The IDs are also not the same if you do this…
> 
> > > o.object\_id == l.order.object\_id  
> > > The parent Order’s value is never updated because it is a different  
> > > object instance than the Order that the line item has a reference to.  
> > > Am I doing something wrong or is this always the case in Rails? Any  
> > > help would be much appreciated.
> 
> Regards,  
> Jason

They’re different ruby objects. But you should be able to do: @order  
== @line\_item.order, since that checks the #id of both records.

In your LineItem class, you’ll have to save the order to the database  
and reload any instances you have in memory to see the changes  
reflected.

–  
Rick O.  
[http://lighthouseapp.com](http://lighthouseapp.com)  
[http://weblog.techno-weenie.net](http://weblog.techno-weenie.net)  
[http://mephistoblog.com](http://mephistoblog.com)

---

<div class="post-metadata">

**Author:** ![jfoxny](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a6a055/32.png) [@jfoxny](https://www.ruby-forum.com/u/jfoxny)\
**Post date:** [August 2, 2007, 8:45pm UTC](https://www.ruby-forum.com/t/unequal-object-identities-in-rails/111109/3 "2007-08-02T20:45:15Z")

</div>

Jason F. wrote:

> … the line item would have a _reference_ to the same (Ruby) order  
> object in memory since I’m including the line items in the load AND  
> using an _Array_ method to select the object. It seems wasteful to have  
> the line item keep it’s own copy of the order object in memory and makes  
> it difficult to encapsulate functionality cleanly.

I just played around with this. It’s even worse than that.

After these two lines

> > o = Order.find(:first, :include =\> :line\_items)  
> > l = o.line\_items.select{ |l| true }.first

the l object does not have any order attribute at all. In the third  
line,

> > o.object\_id == l.order.object\_id

l.order actually loads a new order object with a new SQL query.

Seems wasteful to me too.

---

<div class="post-metadata">

**Author:** ![jfoxny](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a6a055/32.png) [@jfoxny](https://www.ruby-forum.com/u/jfoxny)\
**Post date:** [August 2, 2007, 7:31pm UTC](https://www.ruby-forum.com/t/unequal-object-identities-in-rails/111109/4 "2007-08-02T19:31:54Z")

</div>

Rick O. wrote:

> In your LineItem class, you’ll have to save the order to the database  
> and reload any instances you have in memory to see the changes  
> reflected.

Any idea why it is implemented this way? At the very least I would  
think that under this scenario…

> > o = Order.find(:first, :include =\> :line\_items)  
> > l = o.line\_items.select{ |l| true }.first  
> > o.object\_id == l.order.object\_id  
> > =\> false

… the line item would have a _reference_ to the same (Ruby) order  
object in memory since I’m including the line items in the load AND  
using an _Array_ method to select the object. It seems wasteful to have  
the line item keep it’s own copy of the order object in memory and makes  
it difficult to encapsulate functionality cleanly.

I don’t mean to shoot the messenger with this post. I’m just wondering  
if you (or anyone else) could shed some light on the implementation  
motivations here.

Thanks for the quick reply.

Regards,  
Jason

---

<div class="post-metadata">

**Author:** ![jfoxny](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a6a055/32.png) [@jfoxny](https://www.ruby-forum.com/u/jfoxny)\
**Post date:** [August 2, 2007, 8:57pm UTC](https://www.ruby-forum.com/t/unequal-object-identities-in-rails/111109/5 "2007-08-02T20:57:10Z")

</div>

> Seems wasteful to me too.

Proper ORM identity systems are tough to get right, and just not a big  
deal 90% of the time. Consider this situation:

o1 = Order.find 1  
o2 = Order.find 1, :include =\> :line\_items

Two “equal” orders, but very different because one has the line\_items  
pre-ordered.

In your case you can do this:

o = Order.find(:first, :include =\> {:line\_items =\> :order})

But, that generates an SQL query of WTF proportions.

I wrote about this in more depth on my blog, going into the query  
caching stuff in Edge Rails, and an active\_record\_context plugin I  
wrote. They’re both very simple implementations of an identity system  
that help out in most of the common cases:

[http://activereload.net/2007/5/23/spend-less-time-in-the-database-and-more-time-outdoors](http://activereload.net/2007/5/23/spend-less-time-in-the-database-and-more-time-outdoors)

–  
Rick O.  
[http://lighthouseapp.com](http://lighthouseapp.com)  
[http://weblog.techno-weenie.net](http://weblog.techno-weenie.net)  
[http://mephistoblog.com](http://mephistoblog.com)
