Edoardo "Dado" Marcora
2006-Mar-15 03:10 UTC
[Rails] Self-referential join model does not work
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
See if the patch at http://dev.rubyonrails.org/ticket/4289 works for you. It adds the :association_foreign_key to has_many. On 3/14/06, Edoardo Dado Marcora <marcora@caltech.edu> wrote:> 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 > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Edoardo Dado Marcora
2006-Mar-20 05:18 UTC
[Rails] Re: Self-referential join model does not work
Thanx for adding the ticket and for coming up with the patch. I am sure things will be resolved quickly in rails/trunk. Lee Marlow wrote:> See if the patch at http://dev.rubyonrails.org/ticket/4289 works for > you. It adds the :association_foreign_key to has_many.-- Posted via http://www.ruby-forum.com/.
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 On 3/15/06, Edoardo Dado Marcora <marcora@caltech.edu> wrote:> 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 > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >