Skip to content

Commit

Permalink
Update counter cache in memory if parent target is existed
Browse files Browse the repository at this point in the history
Fixes #19550.
  • Loading branch information
kamipo committed Sep 26, 2018
1 parent 29c23cc commit 38fae1f
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 10 deletions.
13 changes: 3 additions & 10 deletions activerecord/lib/active_record/associations/builder/belongs_to.rb
Expand Up @@ -31,24 +31,17 @@ def self.add_counter_cache_methods(mixin)

mixin.class_eval do
def belongs_to_counter_cache_after_update(reflection)
foreign_key = reflection.foreign_key
cache_column = reflection.counter_cache_column

if association(reflection.name).target_changed?
if reflection.polymorphic?
model = attribute_in_database(reflection.foreign_type).try(:constantize)
model_was = attribute_before_last_save(reflection.foreign_type).try(:constantize)
else
model = reflection.klass
model_was = reflection.klass
end

foreign_key_was = attribute_before_last_save foreign_key
foreign_key = attribute_in_database foreign_key
foreign_key_was = attribute_before_last_save(reflection.foreign_key)
cache_column = reflection.counter_cache_column

if foreign_key && model < ActiveRecord::Base
counter_cache_target(reflection, model, foreign_key).update_counters(cache_column => 1)
end
association(reflection.name).increment_counters

if foreign_key_was && model_was < ActiveRecord::Base
counter_cache_target(reflection, model_was, foreign_key_was).update_counters(cache_column => -1)
Expand Down
32 changes: 32 additions & 0 deletions activerecord/test/cases/associations/has_many_associations_test.rb
Expand Up @@ -1197,6 +1197,38 @@ def test_counter_cache_updates_in_memory_after_create_with_array
assert_equal 2, topic.reload.replies.size
end

def test_counter_cache_updates_in_memory_after_update_with_inverse_of_disabled
topic = Topic.create!(title: "Zoom-zoom-zoom")

assert_equal 0, topic.replies_count

reply1 = Reply.create!(title: "re: zoom", content: "speedy quick!")
reply2 = Reply.create!(title: "re: zoom 2", content: "OMG lol!")

assert_queries(6) do
topic.replies << [reply1, reply2]
end

assert_equal 2, topic.replies_count
assert_equal 2, topic.reload.replies_count
end

def test_counter_cache_updates_in_memory_after_update_with_inverse_of_enabled
category = Category.create!(name: "Counter Cache")

assert_nil category.categorizations_count

categorization1 = Categorization.create!
categorization2 = Categorization.create!

assert_queries(4) do
category.categorizations << [categorization1, categorization2]
end

assert_equal 2, category.categorizations_count
assert_equal 2, category.reload.categorizations_count
end

def test_pushing_association_updates_counter_cache
topic = Topic.order("id ASC").first
reply = Reply.create!
Expand Down

0 comments on commit 38fae1f

Please sign in to comment.