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