Skip to content

Commit

Permalink
fix root lftq increment on update when virtual root
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicolae Claudius committed Jun 20, 2012
1 parent 38e9c5d commit f9fd648
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 12 deletions.
19 changes: 11 additions & 8 deletions lib/acts_as_nested_interval/instance_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def set_nested_interval(lftp, lftq)

def set_nested_interval_for_top
if self.class.virtual_root
set_nested_interval *next_root_lft
set_nested_interval(*next_root_lft)
else
set_nested_interval 0, 1
end
Expand Down Expand Up @@ -100,15 +100,18 @@ def nested_interval_scope
# Updates record, updating descendants if parent association updated,
# in which case caller should first acquire table lock.
def update_nested_interval
if read_attribute(nested_interval_foreign_key).nil?
set_nested_interval_for_top
elsif !association(:parent).updated?
changed = send(:"#{nested_interval_foreign_key}_changed?")
if !changed
db_self = self.class.find(id, :lock => true)
write_attribute(nested_interval_foreign_key, db_self.read_attribute(nested_interval_foreign_key))
set_nested_interval db_self.lftp, db_self.lftq
else # move
# No locking in this case -- caller should have acquired table lock.
update_nested_interval_move
else
if read_attribute(nested_interval_foreign_key).nil? # root move
set_nested_interval_for_top
else # child move
# No locking in this case -- caller should have acquired table lock.
update_nested_interval_move
end
end
end

Expand Down Expand Up @@ -217,4 +220,4 @@ def next_root_lft
end

end
end
end
32 changes: 28 additions & 4 deletions test/acts_as_nested_interval_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@ def test_virtual_root_allocation
r2 = Region.create name: "Romania", :parent => r1
r3 = Region.create name: "Asia"
r4 = Region.create name: "America"
assert_equal [["Europe", 0.5, 1.0], ["Romania", 0.6666666666666666, 1.0],
["Asia", 0.3333333333333333, 0.5], ["America", 0.25, 0.3333333333333333]],
assert_equal [["Europe", 1.0/2, 1.0], ["Romania", 2.0/3, 1.0],
["Asia", 1.0/3, 1.0/2], ["America", 1.0/4, 1.0/3]],
Region.preorder.map { |r| [r.name, r.lft, r.rgt] }
end

Expand All @@ -190,9 +190,33 @@ def test_rebuild_nested_interval_tree
r3 = Region.create name: "Asia"
r4 = Region.create name: "America"
Region.rebuild_nested_interval_tree!
assert_equal [["Europe", 0.5, 1.0], ["Romania", 0.6666666666666666, 1.0],
["Asia", 0.3333333333333333, 0.5], ["America", 0.25, 0.3333333333333333]],
assert_equal [["Europe", 0.5, 1.0], ["Romania", 2.0/3, 1.0],
["Asia", 1.0/3, 1.0/2], ["America", 1.0/4, 1.0/3]],
Region.preorder.map { |r| [r.name, r.lft, r.rgt] }
end

def test_root_update_keeps_interval
Region.virtual_root = true
r1 = Region.create name: "Europe"
r2 = Region.create name: "Romania", parent: r1
r3 = Region.create name: "Asia"
r4 = Region.create name: "America"
lftq = r4.lftq
r4.name = 'USA'
r4.save
assert_equal lftq, r4.lftq
end

def test_move_to_root_recomputes_interval
Region.virtual_root = true
r1 = Region.create name: "Europe"
r2 = Region.create name: "Romania", parent: r1
r3 = Region.create name: "Asia"
r4 = Region.create name: "America"
lftq = r2.lftq
r2.parent = nil
r2.save
assert_not_equal lftq, r2.lftq
end

end

0 comments on commit f9fd648

Please sign in to comment.