Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fix creating children in after_* callbacks

Previously creating children in an after_* callback would cause the
child's ancestry column to contain just the parent id and not the entire
ancestry path.

A workaround was to call self.reload in the after_* callback, but this
commit makes the process work automatically.

The main issue looked to be that the child_ancestry method was using the
ancestry path before the save (using _was) which for new records was
obviously blank.

This revision uses the current value of the parent's ancestry, and adds
a child_ancestry_was method to return the old behaviour (with a more
descriptive name).

The change to update_descendants_with_new_ancestry was due to it relying
on the old behaviour. The revised version explicitly replaces the old
parent ancestry snippet (using child_ancestry_was) with the new one
path.
  • Loading branch information...
commit 9095963857efc567b6e8aebfe38e0a9a21ffcd62 1 parent 65786f0
Jason Stirk authored
Showing with 14 additions and 6 deletions.
  1. +14 −5 lib/ancestry/instance_methods.rb
  2. +0 −1  test/has_ancestry_test.rb
View
19 lib/ancestry/instance_methods.rb
@@ -18,8 +18,8 @@ def update_descendants_with_new_ancestry
descendant.update_attribute(
self.base_class.ancestry_column,
descendant.read_attribute(descendant.class.ancestry_column).gsub(
- /^#{self.child_ancestry}/,
- if read_attribute(self.class.ancestry_column).blank? then id.to_s else "#{read_attribute self.class.ancestry_column }/#{id}" end
+ /^#{self.child_ancestry_was}/,
+ self.child_ancestry
)
)
end
@@ -61,7 +61,16 @@ def child_ancestry
# New records cannot have children
raise Ancestry::AncestryException.new('No child ancestry for new record. Save record before performing tree operations.') if new_record?
- if self.send("#{self.base_class.ancestry_column}_was").blank? then id.to_s else "#{self.send "#{self.base_class.ancestry_column}_was"}/#{id}" end
+ ancestry = self.send(self.ancestry_column)
+ if ancestry.blank? then self.id.to_s else ancestry.to_s + "/#{self.id.to_s}" end
+ end
+
+ def child_ancestry_was
+ # New records cannot have children
+ raise Ancestry::AncestryException.new('No child ancestry for new record. Save record before performing tree operations.') if new_record?
+
+ ancestry = self.send("#{self.ancestry_column}_was")
+ if ancestry.blank? then self.id.to_s else ancestry.to_s + "/#{self.id.to_s}" end
end
# Ancestors
@@ -171,7 +180,7 @@ def is_only_child?
# Descendants
def descendant_conditions
- ["#{self.base_class.table_name}.#{self.base_class.ancestry_column} like ? or #{self.base_class.table_name}.#{self.base_class.ancestry_column} = ?", "#{child_ancestry}/%", child_ancestry]
+ ["#{self.base_class.table_name}.#{self.base_class.ancestry_column} like ? or #{self.base_class.table_name}.#{self.base_class.ancestry_column} = ?", "#{child_ancestry_was}/%", child_ancestry_was]
end
def descendants depth_options = {}
@@ -184,7 +193,7 @@ def descendant_ids depth_options = {}
# Subtree
def subtree_conditions
- ["#{self.base_class.table_name}.#{self.base_class.primary_key} = ? or #{self.base_class.table_name}.#{self.base_class.ancestry_column} like ? or #{self.base_class.table_name}.#{self.base_class.ancestry_column} = ?", self.id, "#{child_ancestry}/%", child_ancestry]
+ ["#{self.base_class.table_name}.#{self.base_class.primary_key} = ? or #{self.base_class.table_name}.#{self.base_class.ancestry_column} like ? or #{self.base_class.table_name}.#{self.base_class.ancestry_column} = ?", self.id, "#{child_ancestry_was}/%", child_ancestry_was]
end
def subtree depth_options = {}
View
1  test/has_ancestry_test.rb
@@ -448,7 +448,6 @@ def test_node_creation_though_scope
end
end
- # NOTE: A workaround for this case is to call self.reload before calling self.children in the after_create
def test_node_creation_in_after_create
AncestryTestDatabase.with_model do |model|
children=[]
Please sign in to comment.
Something went wrong with that request. Please try again.