diff --git a/lib/mongoid_acts_as_tree.rb b/lib/mongoid_acts_as_tree.rb index 80a0e89..2a24dd8 100644 --- a/lib/mongoid_acts_as_tree.rb +++ b/lib/mongoid_acts_as_tree.rb @@ -29,6 +29,13 @@ def acts_as_tree(options = {}) field path_field, :type => Array, :default => [], :index => true field depth_field, :type => Integer, :default => 0 + self.class_eval do + define_method "#{parent_id_field}=" do | new_parent_id | + new_parent = self.class.find new_parent_id + new_parent.children << self + end + end + after_save :move_children validate :will_save_tree before_destroy :destroy_descendants @@ -64,11 +71,11 @@ def will_save_tree def fix_position if parent.nil? - self[parent_id_field] = nil + self.write_attribute parent_id_field, nil self[path_field] = [] self[depth_field] = 0 else - self[parent_id_field] = parent._id + self.write_attribute parent_id_field, parent._id self[path_field] = parent[path_field] + [parent._id] self[depth_field] = parent[depth_field] + 1 self.save @@ -181,7 +188,7 @@ def <<(object) if object.descendants.include? @parent object.instance_variable_set :@_cyclic, true else - object[object.parent_id_field] = @parent._id + object.write_attribute object.parent_id_field, @parent._id object[object.path_field] = @parent[@parent.path_field] + [@parent._id] object[object.depth_field] = @parent[@parent.depth_field] + 1 object.instance_variable_set :@_will_move, true @@ -201,7 +208,7 @@ def delete(object_or_id) object_or_id end - object[object.parent_id_field] = nil + object.write_attribute object.parent_id_field, nil object[object.path_field] = [] object[object.depth_field] = 0 object.save diff --git a/test/test_tree.rb b/test/test_tree.rb index aef5748..f062b70 100644 --- a/test/test_tree.rb +++ b/test/test_tree.rb @@ -53,6 +53,37 @@ class TestMongoidActsAsTree < Test::Unit::TestCase assert eql_arrays?(Category.roots, [@root_1, @root_2]) end + should "assign parent_id" do + child = Category.create :name => 'child' + parent = Category.create :name => 'parent' + + child.parent_id = parent.id + child.save + + assert_equal parent.children.first.id, child.id + assert_equal parent.id, child.parent_id + assert parent.children.include? child + + assert_equal 1, child.depth + assert_equal [parent.id], child.path + + more_deep_child = Category.create :name => 'more deep child' + more_deep_child.parent_id = child.id + + assert_equal child.children.first.id, more_deep_child.id + assert_equal child.id, more_deep_child.parent_id + assert child.children.include? more_deep_child + + assert_equal 2, more_deep_child.depth + assert_equal [parent.id, child.id], more_deep_child.path + + assert parent.descendants.include? child + assert parent.descendants.include? more_deep_child + + assert more_deep_child.ancestors.include? child + assert more_deep_child.ancestors.include? parent + end + context "node" do should "have a root" do assert_equal @root_1.root, @root_1