Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

counter_cache's on parents need to be updated if they are moved to an…

…other node

Ported from
saturnflyer@bac1762#diff-1
thanks Joel Junstrom
  • Loading branch information...
commit a06f8c98f08e8b2cba36a32bd87cc84a34b4c9e4 1 parent 2d565bf
@amerine authored
View
11 lib/acts_as_tree/active_record/acts/tree.rb
@@ -75,6 +75,8 @@ def acts_as_tree(options = {})
class_eval <<-EOV
include ActiveRecord::Acts::Tree::InstanceMethods
+ after_update :update_parents_counter_cache
+
def self.roots
find(:all, :conditions => "#{configuration[:foreign_key]} IS NULL",
:order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}})
@@ -125,6 +127,15 @@ def self_and_siblings
def self_and_children
[self] + self.children
end
+
+ private
+
+ def update_parents_counter_cache
+ if self.respond_to?(:children_count) && parent_id_changed?
+ self.class.decrement_counter(:children_count, parent_id_was)
+ self.class.increment_counter(:children_count, parent_id)
+ end
+ end
end
end
end
View
41 test/acts_as_tree_test.rb
@@ -26,6 +26,7 @@ def setup_db
create_table :mixins do |t|
t.column :type, :string
t.column :parent_id, :integer
+ t.column :children_count, :integer, :default => 0
end
end
end
@@ -51,6 +52,10 @@ class TreeMixinNullify < Mixin
acts_as_tree :foreign_key => "parent_id", :order => "id", :dependent => :nullify
end
+class TreeMixinWithCounterCache < Mixin
+ acts_as_tree :foreign_key => "parent_id", :order => "id", :counter_cache => :children_count
+end
+
class RecursivelyCascadedTreeMixin < Mixin
acts_as_tree :foreign_key => "parent_id"
has_one :first_child, :class_name => 'RecursivelyCascadedTreeMixin', :foreign_key => :parent_id
@@ -103,7 +108,7 @@ def test_insert
assert_equal @extra.parent, @root1
- assert_equal 3, @root1.children.size
+ assert_equal 3, @root1.reload.children.count
assert @root1.children.include?(@extra)
assert @root1.children.include?(@root_child1)
assert @root1.children.include?(@root_child2)
@@ -193,9 +198,9 @@ def test_eager_association_loading
roots = TreeMixin.find(:all, :include => :children, :conditions => "mixins.parent_id IS NULL", :order => "mixins.id")
assert_equal [@root1, @root2, @root3], roots
assert_no_queries do
- assert_equal 2, roots[0].children.size
- assert_equal 0, roots[1].children.size
- assert_equal 0, roots[2].children.size
+ assert_equal 2, roots[0].children.count
+ assert_equal 0, roots[1].children.count
+ assert_equal 0, roots[2].children.count
end
end
@@ -252,3 +257,31 @@ def test_inverse_of
assert_equal @root, @root_child.parent
end
end
+
+
+class TreeTestWithCounterCache < Test::Unit::TestCase
+ def setup
+ teardown_db
+ setup_db
+ @root = TreeMixinWithCounterCache.create!
+ @child1 = TreeMixinWithCounterCache.create! :parent_id => @root.id
+ @child1_child1 = TreeMixinWithCounterCache.create! :parent_id => @child1.id
+ @child2 = TreeMixinWithCounterCache.create! :parent_id => @root.id
+ end
+
+ def teardown
+ teardown_db
+ end
+
+ def test_counter_cache
+ assert_equal 2, @root.reload.children_count
+ assert_equal 1, @child1.reload.children_count
+ end
+
+ def test_update_parents_counter_cache
+ @child1_child1.update_attributes(:parent_id => @root.id)
+ assert_equal 3, @root.reload.children_count
+ assert_equal 0, @child1.reload.children_count
+ end
+
+end
Please sign in to comment.
Something went wrong with that request. Please try again.