From c3e3577f9d5058382504773bf0d32afa15cb131e Mon Sep 17 00:00:00 2001 From: Tom Kadwill <tomkadwill@gmail.com> Date: Sat, 23 Apr 2016 22:14:10 +0100 Subject: Fix counter_cache double increment bug --- .../lib/active_record/associations/belongs_to_association.rb | 1 + .../lib/active_record/associations/builder/belongs_to.rb | 2 ++ .../test/cases/associations/belongs_to_associations_test.rb | 11 +++++++++++ 3 files changed, 14 insertions(+) diff --git a/activerecord/lib/active_record/associations/belongs_to_association.rb b/activerecord/lib/active_record/associations/belongs_to_association.rb index 41698c5360..24997370b2 100644 --- a/activerecord/lib/active_record/associations/belongs_to_association.rb +++ b/activerecord/lib/active_record/associations/belongs_to_association.rb @@ -61,6 +61,7 @@ module ActiveRecord def update_counters_on_replace(record) if require_counter_update? && different_target?(record) + owner.instance_variable_set :@_after_replace_counter_called, true record.increment!(reflection.counter_cache_column) decrement_counters end diff --git a/activerecord/lib/active_record/associations/builder/belongs_to.rb b/activerecord/lib/active_record/associations/builder/belongs_to.rb index 346329c610..3121e70a04 100644 --- a/activerecord/lib/active_record/associations/builder/belongs_to.rb +++ b/activerecord/lib/active_record/associations/builder/belongs_to.rb @@ -33,6 +33,8 @@ module ActiveRecord::Associations::Builder # :nodoc: if (@_after_create_counter_called ||= false) @_after_create_counter_called = false + elsif (@_after_replace_counter_called ||= false) + @_after_replace_counter_called = false elsif attribute_changed?(foreign_key) && !new_record? if reflection.polymorphic? model = attribute(reflection.foreign_type).try(:constantize) diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb index a3046d526e..eef70f5691 100644 --- a/activerecord/test/cases/associations/belongs_to_associations_test.rb +++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb @@ -700,6 +700,17 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase assert_equal 17, reply.replies.size end + def test_replace_counter_cache + topic = Topic.create(title: "Zoom-zoom-zoom") + reply = Reply.create(title: "re: zoom", content: "speedy quick!") + + reply.topic = topic + reply.save + topic.reload + + assert_equal 1, topic.replies_count + end + def test_association_assignment_sticks post = Post.first -- cgit v1.2.3