Reputation: 5220
I'm using Rails 3.1. I have a model Tree and a model TreeNode, and I've set up a has_many/belongs_to association between Tree and TreeNodes.
# The initial models and associations.
class Tree < ActiveRecord::Base
has_many :tree_nodes
end
class TreeNode < ActiveRecord::Base
belongs_to :tree
end
I want to add the concept of a root node, which isn't necessarily the node that was created first. I can't implicitly determine the root node through created_date, primary key (id), or an order (since there isn't a concept of order with nodes). I'm trying to wrap my head around how to set up this association in Rails.
I started off by adding a root_node column with a foreign key on the Tree table, but my Active Record association would then be Tree belongs_to Node and Node has_one Tree. This is because the class that has the foreign key should have the "belongs_to" association, and the other class should have the "has_one" association. This doesn't sound right to me.
# This code didn't work.
class Tree < ActiveRecord::Base
has_many :script_steps
belongs_to :root_tree_node, :class => 'TreeNode'
end
class TreeNode < ActiveRecord::Base
belongs_to :tree
has_one :tree
end
I also tried creating a join table with has_one :through, but the associations wouldn't work either.
# This code didn't work.
class Tree < ActiveRecord::Base
has_many :script_steps
has_one :root_node, :class => 'TreeNode', :through => :root_tree_node
end
class TreeNode < ActiveRecord::Base
belongs_to :tree
has_one :root_tree_node
end
# This represents the join table.
class RootTreeNode < ActiveRecord::Base
belongs_to :tree
belongs_to :tree_node
end
What's the best way to model this relationship generally speaking, and what's the best way to set up the associations in ActiveRecord? At the end of the day, I want to be able to do something like this.
tree = Tree.create
some_node = tree.tree_nodes.create
another_node = tree.tree_nodes.create
tree.root_node = another_node
tree.save
Upvotes: 2
Views: 917
Reputation: 7705
Hmm... If you trying to get normal tree structure like for example category tree one way to do this in rails is this:
def Category < ActiveRecord::Base
belongs_to :parent, :class_name => "Category", :foreign_key => :parent_id
end
This means that each row has reference to its parent. Root node is the one with
parent_id == nil
Leaf node is when it's id is never used as parent_id. For more information check out acts_as_tree plugin (not sure if it works with rails 3).
Other option that you can find more usefull is nested_set (read more here)
Upvotes: 0