From 6137a4e8f77f0bba78d304d962b89ddf3cf465aa Mon Sep 17 00:00:00 2001 From: Lisa Ugray Date: Wed, 12 Jul 2017 10:22:20 -0400 Subject: Add test for fixed `counter_cache` double increment When an `after_create` callback did `update_attributes` on a record with multiple `belongs_to` associations with counter caches, even numbered associations would have their counters double-incremented. Fixes to `ActiveModel::Dirty` in 020abad fixed this. This adds regression tests for this bug fixed incidentally in the other commit, which also removed the need for the workaround using @_after_create_counter_called. --- .../lib/active_record/associations/builder/belongs_to.rb | 4 +--- activerecord/lib/active_record/counter_cache.rb | 1 - .../test/cases/associations/belongs_to_associations_test.rb | 11 +++++++++++ activerecord/test/models/comment.rb | 6 ++++++ 4 files changed, 18 insertions(+), 4 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations/builder/belongs_to.rb b/activerecord/lib/active_record/associations/builder/belongs_to.rb index 2b9dd8aae8..e2763b47e6 100644 --- a/activerecord/lib/active_record/associations/builder/belongs_to.rb +++ b/activerecord/lib/active_record/associations/builder/belongs_to.rb @@ -32,9 +32,7 @@ module ActiveRecord::Associations::Builder # :nodoc: foreign_key = reflection.foreign_key cache_column = reflection.counter_cache_column - if (@_after_create_counter_called ||= false) - @_after_create_counter_called = false - elsif (@_after_replace_counter_called ||= false) + if (@_after_replace_counter_called ||= false) @_after_replace_counter_called = false elsif saved_change_to_attribute?(foreign_key) && !new_record? if reflection.polymorphic? diff --git a/activerecord/lib/active_record/counter_cache.rb b/activerecord/lib/active_record/counter_cache.rb index cbd71a3779..daf0eec3c2 100644 --- a/activerecord/lib/active_record/counter_cache.rb +++ b/activerecord/lib/active_record/counter_cache.rb @@ -180,7 +180,6 @@ module ActiveRecord each_counter_cached_associations do |association| if send(association.reflection.name) association.increment_counters - @_after_create_counter_called = true end end diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb index a7ac291f23..7270060639 100644 --- a/activerecord/test/cases/associations/belongs_to_associations_test.rb +++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb @@ -1167,6 +1167,17 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase Column.create! record: record assert_equal 1, Column.count end + + def test_multiple_counter_cache_with_after_create_update + post = posts(:welcome) + parent = comments(:greetings) + + assert_difference "parent.reload.children_count", +1 do + assert_difference "post.reload.comments_count", +1 do + comment = CommentWithAfterCreateUpdate.create(body: "foo", post: post, parent: parent) + end + end + end end class BelongsToWithForeignKeyTest < ActiveRecord::TestCase diff --git a/activerecord/test/models/comment.rb b/activerecord/test/models/comment.rb index dc2d421cd7..6eff268dd6 100644 --- a/activerecord/test/models/comment.rb +++ b/activerecord/test/models/comment.rb @@ -75,3 +75,9 @@ class CommentWithDefaultScopeReferencesAssociation < Comment default_scope -> { includes(:developer).order("developers.name").references(:developer) } belongs_to :developer end + +class CommentWithAfterCreateUpdate < Comment + after_create do + update_attributes(body: "bar") + end +end -- cgit v1.2.3