Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add clone_with_modifications! method and tests/documentation

  • Loading branch information...
commit 9effe4c9c24d5d0e2d33c4aa01814467582c139c 1 parent 5991984
@ckdake authored
View
20 README.rdoc
@@ -221,6 +221,26 @@ For example, from IRB:
Additionally, if you think something is wrong with your depth cache:
>> TreeNode.rebuild_depth_cache!
+
+= Copying
+
+Ancestry provides a method to clone a tree, optionally replacing attributes and/or preserving a reference to the parent. This allows the creation of structures that use a 'default' tree and make copies of it. Example
+
+ class Category < ActiveRecord::Base
+ belongs_to :project
+ belongs_to :source_category, :class_name => "Category"
+ scope :defaults, where(:project_id => nil)
+
+ def self.import_from_defaults_for(project)
+ defaults.roots.all.each do |root|
+ root.clone_with_modifications!({:project_id => project.id}, nil, :source_category_id)
+ end
+ end
+
+ class Project < ActiveRecord::Base
+ has_many :categories, :dependent => :destroy
+ after_create Proc.new { |p| Category.import_from_defaults_for(self) }
+ end
= Tests
View
13 lib/ancestry/instance_methods.rb
@@ -55,6 +55,19 @@ def apply_orphan_strategy
end
end
end
+
+ # Clone an object and all children
+ # => replacing values with those from attributes if present
+ # => setting parent to new parent if present
+ # => setting the "original_id_field_name" if present to the id of the original object
+ def clone_with_modifications!(attributes = nil, parent = nil, original_id_field_name = nil)
+ clone = self.class.create!(self.attributes.merge(:ancestry => nil).merge(attributes))
+ clone.send("#{original_id_field_name}=", self.id) if original_id_field_name
+ clone.parent = parent
+ self.children.each { |child| child.clone_with_modifications!(attributes, clone, original_id_field_name) }
+ clone.save!
+ clone
+ end
# The ancestry value for this record's children
def child_ancestry
View
18 test/has_ancestry_test.rb
@@ -701,4 +701,22 @@ def test_sort_by_ancestry
assert_equal [n1, n2, n4, n3, n5].map(&:id), arranged.map(&:id)
end
end
+
+ def test_clone_with_modifications!
+ AncestryTestDatabase.with_model :extra_columns => {:source_id => :integer, :project_id => :integer} do |model|
+ n1 = model.create!(:project_id => nil)
+ n2 = model.create!(:parent => n1, :project_id => nil)
+ n3 = model.create!(:parent => n2, :project_id => nil)
+ n4 = model.create!(:parent => n2, :project_id => nil)
+ n5 = model.create!(:parent => n1, :project_id => nil)
+
+ n1c = n1.clone_with_modifications!({:project_id => 1}, nil, :source_id)
+
+ assert_equal n1.id, n1c.source_id
+ assert_equal 1, n1c.project_id
+ assert_equal n1.descendants.count, n1c.descendants.count
+ assert_equal 1, n1c.descendants.last.project_id
+ assert_equal n1.descendants.last.id, n1c.descendants.last.source_id
+ end
+ end
end
Please sign in to comment.
Something went wrong with that request. Please try again.