# Wrong value for belongs\_to?

**URL:** <https://www.ruby-forum.com/t/wrong-value-for-belongs-to/177375>\
**Category:** Rails\
**Created:** [October 15, 2009, 11:30pm UTC](https://www.ruby-forum.com/t/wrong-value-for-belongs-to/177375 "2009-10-15T23:30:20Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![RussK](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/9fc348/32.png) [@RussK](https://www.ruby-forum.com/u/RussK)\
**Post date:** [October 15, 2009, 11:30pm UTC](https://www.ruby-forum.com/t/wrong-value-for-belongs-to/177375/1 "2009-10-15T23:30:20Z")

</div>

I have a class that represents a simple tree (but usually it’s flat).  
It appears that the belongs\_to relationship is returning the wrong  
ID. The class looks like:

class AssetNode \< ActiveRecord::Base  
belongs\_to :asset\_node # parent  
has\_many :asset\_nodes # children  
has\_and\_belongs\_to\_many :assets # leaf nodes

The schema looks like:

CREATE TABLE “asset\_nodes” (“id” INTEGER PRIMARY KEY AUTOINCREMENT NOT  
NULL, “node\_type” integer, “impact\_factor” float DEFAULT 1.0,  
“asset\_node\_id” integer, “service\_id” integer, “created\_at” datetime,  
“updated\_at” datetime);

and a query of the DB looks like:

sqlite\> select \* from asset\_nodes;  
833850115|1|88.8||1217222815|2009-10-15 12:52:26|2009-10-15 12:52:26  
833850116|2|99.9|833850115||2009-10-15 12:52:26|2009-10-15 12:52:26

For a simple test, I fetch the asset node represented by that last  
row, then fetch its parent, by following the asset\_node association.  
But it takes two passes to get the right node:

def test\_should\_compute\_impact\_factor  
asset = assets(:va2)  
an8 = asset.asset\_nodes[0]  
puts “an8 asset node is #{an8} #{an8.id}, IF is #  
{an8.impact\_factor}”  
puts " parent asset\_node\_id is #{an8.asset\_node\_id}"  
an7 = an8.asset\_node  
puts “an7 is #{an7} #{an7.id}, IF is #{an7.impact\_factor}”  
puts " parent asset\_node\_id is #{an7.asset\_node\_id}"  
anx = an7.asset\_node  
puts “an7’s parent (which should not exist) is #{anx} #{anx.id},  
IF is #{anx.impact\_factor}”

I expect the an7 asset\_node to be returned when I fetch  
an8.asset\_node, but instead I get:

an8 asset node is #AssetNode:0x1030ce3e8 833850116, IF is 99.9  
parent asset\_node\_id is 833850116  
an7 is #AssetNode:0x1030a9278 833850116, IF is 99.9  
parent asset\_node\_id is 833850115  
an7’s parent (which should not exist) is #AssetNode:0x1030a5bf0  
833850115, IF is 88.8

When I look at the SQL queries and responses, they seem correct, but I  
see that an8 is selected twice, which surprises me:

– Find “parent” asset nodes for asset va2  
SELECT \* FROM “asset\_nodes” INNER JOIN “asset\_nodes\_assets” ON  
“asset\_nodes”.id = “asset\_nodes\_assets”.asset\_node\_id WHERE  
(“asset\_nodes\_assets”.asset\_id = 1011883891 );

– This is an8, pointing up to an7  
833850116|2|1.0|833850115||2009-10-13 18:54:49|2009-10-13 18:54:49|  
833850116|1011883891

– Find parent asset node for above (but this is really re-selecting  
an8!)  
SELECT \* FROM “asset\_nodes” WHERE (“asset\_nodes”.“id” = 833850116);

– This is an8 again!  
833850116|2|1.0|833850115||2009-10-13 18:54:49|2009-10-13 18:54:49

– Find next parent  
SELECT \* FROM “asset\_nodes” WHERE (“asset\_nodes”.“id” = 833850115) ;

– This is an7, with no parent asset  
833850115|1|1.0||1217222815|2009-10-13 18:54:49|2009-10-13 18:54:49

What’s going on here? Is it me, or is there a bug somewhere?

-Russ

---

<div class="post-metadata">

**Author:** ![RussK](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/9fc348/32.png) [@RussK](https://www.ruby-forum.com/u/RussK)\
**Post date:** [October 16, 2009, 3:35pm UTC](https://www.ruby-forum.com/t/wrong-value-for-belongs-to/177375/2 "2009-10-16T15:35:38Z")

</div>

RussK wrote:

> I have a class that represents a simple tree (but usually it’s flat).  
> It appears that the belongs\_to relationship is returning the wrong  
> ID. The class looks like:

If you need a basic tree structure, why not just use the acts\_as\_tree  
plugin?

> **[GitHub - rails/acts\_as\_tree: NOTICE: official repository moved to...](https://github.com/rails/acts_as_tree/)**
>
> NOTICE: official repository moved to https://github.com/amerine/acts\_as\_tree - GitHub - rails/acts\_as\_tree: NOTICE: official repository moved to https://github.com/amerine/acts\_as\_tree

Example:  
class Category \< ActiveRecord::Base  
acts\_as\_tree :order =\> “name”  
end

It’s much simpler and gives you a lot of convenience methods for  
traversing the tree.

---

<div class="post-metadata">

**Author:** ![RussK](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/9fc348/32.png) [@RussK](https://www.ruby-forum.com/u/RussK)\
**Post date:** [October 16, 2009, 5:39pm UTC](https://www.ruby-forum.com/t/wrong-value-for-belongs-to/177375/3 "2009-10-16T17:39:17Z")

</div>

Robert W. wrote:

> RussK wrote:
> 
> > I have a class that represents a simple tree (but usually it’s flat).  
> > It appears that the belongs\_to relationship is returning the wrong  
> > ID. The class looks like:
> 
> If you need a basic tree structure, why not just use the acts\_as\_tree  
> plugin?
> 
> [GitHub - rails/acts\_as\_tree: NOTICE: official repository moved to https://github.com/amerine/acts\_as\_tree](http://github.com/rails/acts_as_tree/)
> 
> Example:  
> class Category \< ActiveRecord::Base  
> acts\_as\_tree :order =\> “name”  
> end
> 
> It’s much simpler and gives you a lot of convenience methods for  
> traversing the tree.

Actually, for this use case (as for most!) awesome\_nested\_set would be  
better than acts\_as\_tree. Among other things, it lets you get all  
descendants with a single query, whereas with acts\_as\_tree you have to  
get immediate children and then run more queries.

## Best,

Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![RussK](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/9fc348/32.png) [@RussK](https://www.ruby-forum.com/u/RussK)\
**Post date:** [October 16, 2009, 7:46pm UTC](https://www.ruby-forum.com/t/wrong-value-for-belongs-to/177375/4 "2009-10-16T19:46:10Z")

</div>

Thanks for your responses. Before I posted this question, I looked at  
awesome\_nested\_set. But I have two problems with it: (1) my entire  
application is largely a tree, but the nodes are of different classes  
at different levels, and the nested sets need all nodes to be of the  
same or a derived type, (2) the tree here is almost always flat,  
making the nested set solution way overkill. So I’m just looking to  
understand whether there’s a bug here or I’m misunderstanding how RoR  
handles a self-referential belongs\_to association.

Specifically, I’d like to know why

an7 = an8.asset\_node

Didn’t actually return the object that an8.asset\_node refers to?

-Russ

---

<div class="post-metadata">

**Author:** ![RussK](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/9fc348/32.png) [@RussK](https://www.ruby-forum.com/u/RussK)\
**Post date:** [October 16, 2009, 9:06pm UTC](https://www.ruby-forum.com/t/wrong-value-for-belongs-to/177375/5 "2009-10-16T21:06:32Z")

</div>

RussK wrote:

> Thanks for your responses. Before I posted this question, I looked at  
> awesome\_nested\_set. But I have two problems with it: (1) my entire  
> application is largely a tree, but the nodes are of different classes  
> at different levels, and the nested sets need all nodes to be of the  
> same or a derived type,

That’s easily worked around. Don’t discount nested sets on that basis.

> (2) the tree here is almost always flat,

Um, how can a tree be flat?

> making the nested set solution way overkill.

It’s not overkill. It’s the fist structure you should think of when you  
have anything treelike. You’re trying to reinvent the square wheel with  
your approach, I think. That said, I’ll try to answer your question in  
more detail when I have time.

## Best,

Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![RussK](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/9fc348/32.png) [@RussK](https://www.ruby-forum.com/u/RussK)\
**Post date:** [October 17, 2009, 2:29pm UTC](https://www.ruby-forum.com/t/wrong-value-for-belongs-to/177375/6 "2009-10-17T14:29:59Z")

</div>

> That’s easily worked around. Don’t discount nested sets on that basis.

Working around that would be great for my application overall, as I’d  
like to turn it into one giant tree across multiple, unrelated  
classes. How might that be done?

> > (2) the tree here is almost always flat,
> 
> Um, how can a tree be flat?

The tree typically has a height of zero (just a root).

> > making the nested set solution way overkill.
> 
> It’s not overkill. It’s the fist structure you should think of when you  
> have anything treelike. You’re trying to reinvent the square wheel with  
> your approach, I think. That said, I’ll try to answer your question in  
> more detail when I have time.

Your point is well taken. There is another part of my application  
that has depth and, being ignorant of nested tree, I wrote that  
functionality and will definitely refactor with an awesome tree.  
Oddly, that code seems to work while this part does not.

But my question is not about trees, it’s about why RoR is returning  
the wrong value for an association.

-Russ

---

<div class="post-metadata">

**Author:** ![RussK](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/9fc348/32.png) [@RussK](https://www.ruby-forum.com/u/RussK)\
**Post date:** [October 16, 2009, 11:47pm UTC](https://www.ruby-forum.com/t/wrong-value-for-belongs-to/177375/7 "2009-10-16T23:47:56Z")

</div>

On Oct 15, 12:49 pm, RussK [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> For a simple test, I fetch the asset node represented by that last  
> row, then fetch its parent, by following the asset\_node association.  
> But it takes two passes to get the right node:
> 
> def test\_should\_compute\_impact\_factor  
> asset = assets(:va2)  
> an8 = asset.asset\_nodes[0]

There’s definitely _something_ weird going on. Can you try putting  
an8.reload here in the code and see if it changes the results? The  
only thing I can think of is the HABTM is somehow leaving incorrect  
data behind.

–Matt J.

---

<div class="post-metadata">

**Author:** ![RussK](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/9fc348/32.png) [@RussK](https://www.ruby-forum.com/u/RussK)\
**Post date:** [October 17, 2009, 2:30pm UTC](https://www.ruby-forum.com/t/wrong-value-for-belongs-to/177375/8 "2009-10-17T14:30:34Z")

</div>

> There’s definitely _something_ weird going on. Can you try putting  
> an8.reload here in the code and see if it changes the results? The  
> only thing I can think of is the HABTM is somehow leaving incorrect  
> data behind.

Sure enough, if I add “an8.reload” then “an7 = an8.asset\_node”  
correctly returns an7. But I noticed in the log that the set of SQL  
queries with and without reload is exactly the same. I expected  
reload to run another query, as the doc says it “Reloads the  
attributes of this object from the database”, but it didn’t.

-Russ

---

<div class="post-metadata">

**Author:** ![RussK](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/9fc348/32.png) [@RussK](https://www.ruby-forum.com/u/RussK)\
**Post date:** [October 23, 2009, 7:05pm UTC](https://www.ruby-forum.com/t/wrong-value-for-belongs-to/177375/9 "2009-10-23T19:05:09Z")

</div>

I found the solution to my problem. The situation is that class A has  
a habtm relationship to class B and also has a has\_many and belongs\_to  
relationship to itself. This results in two columns named a\_id in the  
DB, one in the join table and one in A’s table. When fetching the set  
of As via B, Rails apparently uses the a\_id from the join table to  
construct instances of A. This causes A’s belongs\_to relationship to  
point to itself instead of its real A owner. To fix this, I changed  
A’s habtm to “has\_and\_belongs\_to\_many :bs, :foreign\_key =\> ‘a\_ref’”  
and B’s habtm to  
“has\_and\_belongs\_to\_many :as, :association\_foreign\_key =\> ‘a\_ref’”,  
with the join table using a\_ref instead of a\_id.

-Russ
