1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Confirm a record has not already been destroyed before decrementing

counter cache

At present, calling destroy multiple times on the same record results
in the belongs_to counter cache being decremented multiple times. With
this change the record is checked for whether it is already destroyed
prior to decrementing the counter cache.
This commit is contained in:
Ben Tucker 2013-05-06 18:31:20 -04:00
parent f7f8b7ccfc
commit 228720ef19
3 changed files with 27 additions and 1 deletions

View file

@ -1,3 +1,7 @@
* Confirm a record has not already been destroyed before decrementing counter cache.
*Ben Tucker*
* Mute `psql` output when running rake db:schema:load. * Mute `psql` output when running rake db:schema:load.
*Godfrey Chan* *Godfrey Chan*

View file

@ -34,7 +34,9 @@ module ActiveRecord::Associations::Builder
def belongs_to_counter_cache_before_destroy_for_#{name} def belongs_to_counter_cache_before_destroy_for_#{name}
unless destroyed_by_association && destroyed_by_association.foreign_key.to_sym == #{foreign_key.to_sym.inspect} unless destroyed_by_association && destroyed_by_association.foreign_key.to_sym == #{foreign_key.to_sym.inspect}
record = #{name} record = #{name}
record.class.decrement_counter(:#{cache_column}, record.id) unless record.nil? if record && !self.destroyed?
record.class.decrement_counter(:#{cache_column}, record.id)
end
end end
end end

View file

@ -414,6 +414,26 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_equal 15, topic.replies.size assert_equal 15, topic.replies.size
end end
def test_counter_cache_double_destroy
topic = Topic.create :title => "Zoom-zoom-zoom"
5.times do
topic.replies.create(:title => "re: zoom", :content => "speedy quick!")
end
assert_equal 5, topic.reload[:replies_count]
assert_equal 5, topic.replies.size
reply = topic.replies.first
reply.destroy
assert_equal 4, topic.reload[:replies_count]
reply.destroy
assert_equal 4, topic.reload[:replies_count]
assert_equal 4, topic.replies.size
end
def test_custom_counter_cache def test_custom_counter_cache
reply = Reply.create(:title => "re: zoom", :content => "speedy quick!") reply = Reply.create(:title => "re: zoom", :content => "speedy quick!")
assert_equal 0, reply[:replies_count] assert_equal 0, reply[:replies_count]