Skip to content

Commit

Permalink
Added support for counter_cache columns
Browse files Browse the repository at this point in the history
  • Loading branch information
jkrall authored and danielmorrison committed May 6, 2011
1 parent 18d3b15 commit 71ee8b9
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 2 deletions.
7 changes: 6 additions & 1 deletion lib/awesome_nested_set/awesome_nested_set.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ module NestedSet #:nodoc:
# child objects are destroyed alongside this object by calling their destroy
# method. If set to :delete_all (default), all the child objects are deleted
# without calling their destroy method.
# * +:counter_cache+ adds a counter cache for the number of children.
# defaults to false.
# Example: <tt>acts_as_nested_set :counter_cache => :children_count</tt>
#
# See CollectiveIdea::Acts::NestedSet::Model::ClassMethods for a list of class methods and
# CollectiveIdea::Acts::NestedSet::Model::InstanceMethods for a list of instance methods added
Expand All @@ -41,6 +44,7 @@ def acts_as_nested_set(options = {})
:left_column => 'lft',
:right_column => 'rgt',
:dependent => :delete_all, # or :destroy
:counter_cache => false
}.merge(options)

if options[:scope].is_a?(Symbol) && options[:scope].to_s !~ /_id$/
Expand All @@ -55,7 +59,8 @@ def acts_as_nested_set(options = {})
extend Columns

belongs_to :parent, :class_name => self.base_class.to_s,
:foreign_key => parent_column_name
:foreign_key => parent_column_name,
:counter_cache => options[:counter_cache]
has_many :children, :class_name => self.base_class.to_s,
:foreign_key => parent_column_name, :order => quoted_left_column_name

Expand Down
31 changes: 30 additions & 1 deletion spec/awesome_nested_set_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

describe "AwesomeNestedSet" do
before(:all) do
self.class.fixtures :categories, :departments, :notes
self.class.fixtures :categories, :departments, :notes, :things
end

describe "defaults" do
Expand Down Expand Up @@ -791,4 +791,33 @@ def check_structure(entries, structure)
categories(:child_3).save.should be_true
end
end

describe "counter_cache" do

it "should allow use of a counter cache for children" do
note1 = things(:parent1)
assert_equal 2, note1.children.count
end

it "should increment the counter cache on create" do
ActiveRecord::Base.logger.info 'FOO'
note1 = things(:parent1)
assert_equal 2, note1.children.count
assert_equal 2, note1[:children_count]
note1.children.create :body => 'Child 3'
assert_equal 3, note1.children.count
note1.reload
assert_equal 3, note1[:children_count]
end

it "should decrement the counter cache on destroy" do
note1 = things(:parent1)
assert_equal 2, note1.children.count
assert_equal 2, note1[:children_count]
note1.children.last.destroy
assert_equal 1, note1.children.count
note1.reload
assert_equal 1, note1[:children_count]
end
end
end
8 changes: 8 additions & 0 deletions spec/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,12 @@
t.column :red, :integer
t.column :black, :integer
end

create_table :things, :force => true do |t|
t.column :body, :text
t.column :parent_id, :integer
t.column :lft, :integer
t.column :rgt, :integer
t.column :children_count, :integer
end
end
27 changes: 27 additions & 0 deletions spec/fixtures/things.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
parent1:
id: 1
body: Top Level
lft: 1
rgt: 10
children_count: 2
child_1:
id: 2
body: Child 1
parent_id: 1
lft: 2
rgt: 3
children_count: 0
child_2:
id: 3
body: Child 2
parent_id: 1
lft: 4
rgt: 7
children_count: 0
child_2_1:
id: 4
body: Child 2.1
parent_id: 3
lft: 8
rgt: 9
children_count: 0
4 changes: 4 additions & 0 deletions spec/support/models.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,8 @@ def recurse &block
end
}
end
end

class Thing < ActiveRecord::Base
acts_as_nested_set :counter_cache => 'children_count'
end

0 comments on commit 71ee8b9

Please sign in to comment.