Commit 9ec5f94c by Chris Oliver

Fix counter caches for ActiveRecord 4.2+

parent 36adfecb
......@@ -76,6 +76,7 @@ module Paranoia
def destroy
transaction do
run_callbacks(:destroy) do
@_disable_counter_cache = deleted?
result = delete
next result unless result && ActiveRecord::VERSION::STRING >= '4.2'
each_counter_cached_associations do |association|
......@@ -84,6 +85,7 @@ module Paranoia
next unless send(association.reflection.name)
association.decrement_counters
end
@_disable_counter_cache = false
result
end
end
......@@ -110,8 +112,15 @@ module Paranoia
# This only happened on Rails versions earlier than 4.1.
noop_if_frozen = ActiveRecord.version < Gem::Version.new("4.1")
if within_recovery_window?(recovery_window_range) && ((noop_if_frozen && !@attributes.frozen?) || !noop_if_frozen)
@_disable_counter_cache = !deleted?
write_attribute paranoia_column, paranoia_sentinel_value
update_columns(paranoia_restore_attributes)
each_counter_cached_associations do |association|
if send(association.reflection.name)
association.increment_counters
end
end
@_disable_counter_cache = false
end
restore_associated_records(recovery_window_range) if opts[:recursive]
end
......@@ -140,6 +149,7 @@ module Paranoia
def really_destroy!
transaction do
run_callbacks(:real_destroy) do
@_disable_counter_cache = deleted?
dependent_reflections = self.class.reflections.select do |name, reflection|
reflection.options[:dependent] == :destroy
end
......@@ -163,6 +173,10 @@ module Paranoia
private
def each_counter_cached_associations
!@_disable_counter_cache && defined?(super) ? super : []
end
def paranoia_restore_attributes
{
paranoia_column => paranoia_sentinel_value
......
......@@ -1003,6 +1003,44 @@ class ParanoiaTest < test_framework
assert related_model.instance_variable_get(:@after_destroy_callback_called)
assert related_model.instance_variable_get(:@after_commit_on_destroy_callback_called)
end
def test_counter_cache_column_on_double_destroy
parent_model_with_counter_cache_column = ParentModelWithCounterCacheColumn.create
related_model = parent_model_with_counter_cache_column.related_models.create
related_model.destroy
related_model.destroy
assert_equal 0, parent_model_with_counter_cache_column.reload.related_models_count
end
def test_counter_cache_column_on_double_restore
parent_model_with_counter_cache_column = ParentModelWithCounterCacheColumn.create
related_model = parent_model_with_counter_cache_column.related_models.create
related_model.destroy
related_model.restore
related_model.restore
assert_equal 1, parent_model_with_counter_cache_column.reload.related_models_count
end
def test_counter_cache_column_on_destroy_and_really_destroy
parent_model_with_counter_cache_column = ParentModelWithCounterCacheColumn.create
related_model = parent_model_with_counter_cache_column.related_models.create
related_model.destroy
related_model.really_destroy!
assert_equal 0, parent_model_with_counter_cache_column.reload.related_models_count
end
def test_counter_cache_column_on_restore
parent_model_with_counter_cache_column = ParentModelWithCounterCacheColumn.create
related_model = parent_model_with_counter_cache_column.related_models.create
related_model.destroy
assert_equal 0, parent_model_with_counter_cache_column.reload.related_models_count
related_model.restore
assert_equal 1, parent_model_with_counter_cache_column.reload.related_models_count
end
end
private
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment