GlyphGryph
GlyphGryph

Reputation: 4794

How can I has_and_belongs_to_many multiple instances of the same model?

Basically, I want to accomplish something like this:

Class Node < ActiveRecord::Base
  has_and_belongs_to_many :parents, :class_name=>'Node'
  has_and_belongs_to_many :children, :class_name=>'Node'
end

but it isn't working, and I'm not entirely sure the proper way to do this. I'm going to try explicitly defining a join table next and have both use it: If that's the solution, would the column be called "children_id" or "child_id"?

Upvotes: 4

Views: 3874

Answers (2)

tadman
tadman

Reputation: 211740

This is doable, but I strongly recommend using has_many :through instead:

class Node < ActiveRecord::Base
  has_many :parent_node_links,
    :class_name => 'NodeLink',
    :foreign_key => :child_id

  has_many :parents,
    :through => :parent_node_links,
    :source => :parent

  has_many :child_node_links,
    :class_name => 'NodeLink',
    :foreign_key => :parent_id

  has_many :children,
    :through => :child_node_links,
    :source => :child
end

class NodeLink < ActiveRecord::Base
  belongs_to :parent,
    :class_name => "Node"
  belongs_to :child,
    :class_name => "Node"
end

Having a first-class join model makes it much easier to manage the relationships and gives you the freedom to add relevant meta-data at a later point in time.

Upvotes: 7

PinnyM
PinnyM

Reputation: 35541

Class Node < ActiveRecord::Base
  has_and_belongs_to_many :parents, :class_name=>'Node', :join_table => "parents_children", :foreign_key => :child_id, :association_foreign_key => :parent_id
  has_and_belongs_to_many :children, :class_name=>'Node', :join_table => "parents_children", :foreign_key => :parent_id, :association_foreign_key => :child_id
end

Note that you can rename the join table and foreign keys as long as you set the appropriate foreign key names here.

Upvotes: 15

Related Questions