From 34139fcf0cd70d79c1d7f60bce39d31237a67f89 Mon Sep 17 00:00:00 2001 From: Emilio Tagua Date: Tue, 2 Dec 2008 14:12:09 -0300 Subject: [PATCH] Fix: counter_cache should decrement on deleting associated records. --- .../associations/association_collection.rb | 3 +++ .../associations/has_many_associations_test.rb | 20 ++++++++++++++++++++ .../has_many_through_associations_test.rb | 14 ++++++++++++++ 3 files changed, 37 insertions(+), 0 deletions(-) diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index 0ff91fb..0ad5801 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -202,6 +202,9 @@ module ActiveRecord records.each do |record| @target.delete(record) + if respond_to?(:cached_counter_attribute_name) && @owner[cached_counter_attribute_name] + @owner.class.decrement_counter(cached_counter_attribute_name, @owner.send(@owner.class.primary_key)) + end callback(:after_remove, record) end end diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index 816ceb6..1f8b297 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -552,6 +552,18 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal 0, companies(:first_firm).clients_of_firm(true).size end + def test_deleting_updates_counter_cache + post = Post.first + + post.comments.delete(post.comments.first) + post.reload + assert_equal post.comments(true).size, post.comments_count + + post.comments.delete(post.comments.first) + post.reload + assert_equal 0, post.comments_count + end + def test_deleting_before_save new_firm = Firm.new("name" => "A New Firm, Inc.") new_client = new_firm.clients_of_firm.build("name" => "Another Client") @@ -605,6 +617,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end end + def test_clearing_updates_counter_cache + post = Post.first + + post.comments.clear + post.reload + assert_equal 0, post.comments_count + end + def test_clearing_a_dependent_association_collection firm = companies(:first_firm) client_id = firm.dependent_clients_of_firm.first.id diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb index a07f4bc..a2222b7 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -3,6 +3,9 @@ require 'models/post' require 'models/person' require 'models/reader' require 'models/comment' +require 'models/tag' +require 'models/tagging' +require 'models/author' class HasManyThroughAssociationsTest < ActiveRecord::TestCase fixtures :posts, :readers, :people, :comments, :authors @@ -84,6 +87,17 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase assert posts(:welcome).reload.people(true).empty? end + def test_deleting_updates_counter_cache + taggable = Tagging.first.taggable + taggable.taggings.push(Tagging.new) + taggable.reload + assert_equal 1, taggable.taggings_count + + taggable.taggings.delete(taggable.taggings.first) + taggable.reload + assert_equal 0, taggable.taggings_count + end + def test_replace_association assert_queries(4){posts(:welcome);people(:david);people(:michael); posts(:welcome).people(true)} -- 1.5.5.1