Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge remote-tracking branch 'ridsagrawal/master'

Conflicts:
	lib/ancestry/instance_methods.rb
  • Loading branch information...
commit 5c90437974d0e8ca9ee19650b7e4b268d4805270 2 parents cd268b6 + 94dba1c
Stefan Henzen authored
View
1  README.rdoc
@@ -74,6 +74,7 @@ The has_ancestry methods supports the following options:
:destroy All children are destroyed as well (default)
:rootify The children of the destroyed node become root nodes
:restrict An AncestryException is raised if any children exist
+ :parentify The orphan subtree is added to the parent of the deleted node.If the deleted node is Root, then rootify the orphan subtree.
:cache_depth Cache the depth of each node in the 'ancestry_depth' column (default: false)
If you turn depth_caching on for an existing model:
- Migrate: add_column [table], :ancestry_depth, :integer, :default => 0
View
6 lib/ancestry/class_methods.rb
@@ -19,11 +19,11 @@ def scope_depth depth_options, depth
# Orphan strategy writer
def orphan_strategy= orphan_strategy
- # Check value of orphan strategy, only rootify, restrict or destroy is allowed
- if [:rootify, :restrict, :destroy].include? orphan_strategy
+ # Check value of orphan strategy, only rootify, adopt, restrict or destroy is allowed
+ if [:rootify, :adopt, :restrict, :destroy].include? orphan_strategy
class_variable_set :@@orphan_strategy, orphan_strategy
else
- raise Ancestry::AncestryException.new("Invalid orphan strategy, valid ones are :rootify, :restrict and :destroy.")
+ raise Ancestry::AncestryException.new("Invalid orphan strategy, valid ones are :rootify,:adopt, :restrict and :destroy.")
end
end
View
13 lib/ancestry/instance_methods.rb
@@ -27,7 +27,7 @@ def update_descendants_with_new_ancestry
end
end
end
-
+
# Apply orphan strategy
def apply_orphan_strategy
# Skip this if callbacks are disabled
@@ -48,6 +48,14 @@ def apply_orphan_strategy
descendant.destroy
end
end
+ # ... make child elements of this node, child of its parent if orphan strategy is adopt
+ elsif self.base_class.orphan_strategy == :adopt
+ descendants.all.each do |descendant|
+ descendant.without_ancestry_callbacks do
+ new_ancestry = descendant.ancestor_ids.delete_if { |x| x == self.id }.join("/")
+ descendant.update_attribute descendant.class.ancestry_column, new_ancestry || nil
+ end
+ end
# ... throw an exception if it has children and orphan strategy is restrict
elsif self.base_class.orphan_strategy == :restrict
raise Ancestry::AncestryException.new('Cannot delete record because it has descendants.') unless is_childless?
@@ -158,7 +166,7 @@ def siblings
end
def sibling_ids
- siblings.all(:select => self.base_class.primary_key).collect(&self.base_class.primary_key.to_sym)
+ siblings.all(:select => self.base_class.primary_key).collect(&self.base_class.primary_key.to_sym)
end
def has_siblings?
@@ -219,7 +227,6 @@ def cast_primary_key(key)
def primary_key_type
@primary_key_type ||= column_for_attribute(self.class.primary_key).type
end
-
def unscoped_descendants
self.base_class.unscoped do
self.base_class.all(:conditions => descendant_conditions)
View
18 test/has_ancestry_test.rb
@@ -1,6 +1,7 @@
require "environment"
class HasAncestryTreeTest < ActiveSupport::TestCase
+
def test_default_ancestry_column
AncestryTestDatabase.with_model do |model|
assert_equal :ancestry, model.ancestry_column
@@ -302,6 +303,23 @@ def test_orphan_restrict_strategy
end
end
end
+
+ def test_orphan_adopt_strategy
+ AncestryTestDatabase.with_model do |model|
+ model.orphan_strategy = :adopt # set the orphan strategy as paerntify
+ n1 = model.create! #create a root node
+ n2 = model.create!(:parent => n1) #create child with parent=root
+ n3 = model.create!(:parent => n2) #create child with parent=n2, depth = 2
+ n4 = model.create!(:parent => n2) #create child with parent=n2, depth = 2
+ n5 = model.create!(:parent => n4) #create child with parent=n4, depth = 3
+ n2.destroy # delete a node with desecendants
+ assert_equal(model.find(n3.id).parent,n1, "orphan's not parentified" )
+ assert_equal(model.find(n5.id).ancestor_ids,[n1.id,n4.id], "ancestry integrity not maintained")
+ n1.destroy # delete a root node with desecendants
+ assert_equal(model.find(n3.id).parent_id,nil," Children of the deleted root not rootfied")
+ assert_equal(model.find(n5.id).ancestor_ids,[n4.id],"ancestry integrity not maintained")
+ end
+ end
def test_integrity_checking
AncestryTestDatabase.with_model :width => 3, :depth => 3 do |model, roots|
Please sign in to comment.
Something went wrong with that request. Please try again.