diff --git a/lib/closure_tree/acts_as_tree.rb b/lib/closure_tree/acts_as_tree.rb index f3280b2a..6a853217 100644 --- a/lib/closure_tree/acts_as_tree.rb +++ b/lib/closure_tree/acts_as_tree.rb @@ -13,7 +13,8 @@ def acts_as_tree(options = {}) :order, :parent_column_name, :with_advisory_lock, - :touch + :touch, + :cache_child_count ) class_attribute :_ct diff --git a/lib/closure_tree/model.rb b/lib/closure_tree/model.rb index 13f6a820..91d2619d 100644 --- a/lib/closure_tree/model.rb +++ b/lib/closure_tree/model.rb @@ -9,7 +9,8 @@ module Model class_name: _ct.model_class.to_s, foreign_key: _ct.parent_column_name, inverse_of: :children, - touch: _ct.options[:touch] + touch: _ct.options[:touch], + counter_cache: _ct.options[:cache_child_count] ? :child_count : false # TODO, remove when activerecord 3.2 support is dropped attr_accessible :parent if _ct.use_attr_accessible? diff --git a/spec/counter_cache_spec.rb b/spec/counter_cache_spec.rb new file mode 100644 index 00000000..a7e48d1a --- /dev/null +++ b/spec/counter_cache_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' + +describe 'caching child count' do + before do + @root = MenuItem.create + end + + describe 'cache_child_count option' do + it 'should default to 0' do + expect(@root.child_count).to eq(0) + end + + it 'should keep track of the direct children as they are added and removed' do + @root.children << MenuItem.new + expect(@root.reload.child_count).to eq(1) + MenuItem.create(parent: @root) + expect(@root.reload.child_count).to eq(2) + @root.children.first.destroy + expect(@root.reload.child_count).to eq(1) + end + + it 'should not count children of children' do + child_node = MenuItem.new + child_node.children << MenuItem.new + @root.children << child_node + + expect(@root.reload.child_count).to eq(1) + end + end +end diff --git a/spec/db/models.rb b/spec/db/models.rb index b82a6596..cd5e3253 100644 --- a/spec/db/models.rb +++ b/spec/db/models.rb @@ -103,5 +103,5 @@ class Metal < ActiveRecord::Base end class MenuItem < ActiveRecord::Base - acts_as_tree(touch: true, with_advisory_lock: false) + acts_as_tree(touch: true, with_advisory_lock: false, cache_child_count: true) end diff --git a/spec/db/schema.rb b/spec/db/schema.rb index 631070df..40f0b36b 100644 --- a/spec/db/schema.rb +++ b/spec/db/schema.rb @@ -128,6 +128,7 @@ create_table 'menu_items' do |t| t.string 'name' t.integer 'parent_id' + t.integer 'child_count', null: false, default: 0 t.timestamps end