Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Add clone_with_modifications! method and tests/documentation #55

Open
wants to merge 1 commit into from

1 participant

@ckdake

This addresses #36

@ckdake

Any chance you can take a look at this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
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
Something went wrong with that request. Please try again.