Self-referential join model does not work


#1

I have been trying to model a labeled graph using ActiveRecord (trunk
version). Basically, I have a ‘Node’ model which represents a node
linking
to other nodes. Links (aka edges) are labeled (i.e., have a ‘label’
attribute and other behavior). Thus I decided to model edges as an
‘Edge’
model and use a ‘has_many :trough’ association in the Node model.
However,
it just doesn’t work, regardless of how hard I’ve tried.

The database structure is as follows:

class InitialSchema < ActiveRecord::Migration
def self.up
create_table :nodes do |t|
t.column :title, :string, :null => false
t.column :body, :text, :null => false, :default => ‘’
end
create_table :edges do |t|
t.column :node_id, :integer, :null => false
t.column :related_node_id, :integer, :null => false
t.column :label, :string, :null => false, :default => ‘’
end
add_index :edges, [:node_id, :related_node_id], :unique => true
end
def self.down
drop_table :edges
drop_table :nodes
end
end

The two models are as follows:

class Node < ActiveRecord::Base
validates_presence_of :title
has_many :edges, :dependent => true
has_many :related_nodes, :through => :edges, :class_name =>
‘Node’, :foreign_key => ‘node_id’
end

class Edge < ActiveRecord::Base
belongs_to :node
belongs_to :related_node, :class_name => ‘Node’, :foreign_key =>
‘related_node_id’
validates_uniqueness_of :related_node_id, :scope => :node_id
validates_presence_of :node, :related_node
end

In script/console I then create two nodes and link them with an edge as
follows:

from_node = Node.create :title => ‘From’
to_node = Node.create :title => ‘To’
e = Edge.create :node => from_node, :related_node => to_node
from_node.edges.find_first.related_node
=> #<Node:0xb7430ee4 @attributes={“body”=>"", “title”=>“To”, “id”=>“2”}>

SO FAR SO GOOD! but if I ask the ‘from_node’ for ‘related_nodes’ this is
what I get back!!!

from_node.edges.related_nodes.find_first
=> #<Node:0xb742e20c @attributes={“body”=>"", “title”=>“From”,
“id”=>“1”}>

Same result even if I change :foreign_key in the Node model from
‘node_id’
to ‘related_node_id’. Furthermore, :association_foreign_key is not
accepted
as a parameter to has_many :through associations.

Does anybody have a clue of what I am doing wrong here? Or is it that
Rails
1.1 does not support self-referential join models?

Thanx in advance for the help and consideration,

Edoardo “Dado” Marcora


#2

See if the patch at http://dev.rubyonrails.org/ticket/4289 works for
you. It adds the :association_foreign_key to has_many.


#3

Thanx for adding the ticket and for coming up with the patch. I am sure
things will be resolved quickly in rails/trunk.

Lee M. wrote:

See if the patch at http://dev.rubyonrails.org/ticket/4289 works for
you. It adds the :association_foreign_key to has_many.


#4

Did you get this sorted?

I got something that works for me using the lovely :through. I copied
it onto a blogger account since it would have been real messy here…

http://rubbishshoes.blogspot.com/2006/03/self-referential-many-many-using.html

beers
-h