aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorLisa Ugray <lisa.ugray@shopify.com>2017-07-12 10:22:20 -0400
committerLisa Ugray <lisa.ugray@shopify.com>2017-07-19 07:13:19 -0400
commit6137a4e8f77f0bba78d304d962b89ddf3cf465aa (patch)
tree3d4b07df17dd045ca525b6ef34d786c5244d9954 /activerecord
parenta6d6e90fa90eedbdb6d3cda679aa4b47ddfa7315 (diff)
downloadrails-6137a4e8f77f0bba78d304d962b89ddf3cf465aa.tar.gz
rails-6137a4e8f77f0bba78d304d962b89ddf3cf465aa.tar.bz2
rails-6137a4e8f77f0bba78d304d962b89ddf3cf465aa.zip
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.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/associations/builder/belongs_to.rb4
-rw-r--r--activerecord/lib/active_record/counter_cache.rb1
-rw-r--r--activerecord/test/cases/associations/belongs_to_associations_test.rb11
-rw-r--r--activerecord/test/models/comment.rb6
4 files changed, 18 insertions, 4 deletions
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