Skip to content

Commit

Permalink
move Rails 4.2 counter cached associations destroy inside callbacks
Browse files Browse the repository at this point in the history
This will allow to detect counter cached columns changes in callbacks
like `after_destroy` or `after_commit on: :destroy`.
  • Loading branch information
sergey-alekseev committed Feb 17, 2015
1 parent 3a48a05 commit 46d9970
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 14 deletions.
23 changes: 9 additions & 14 deletions lib/paranoia.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,24 +66,19 @@ def self.extended(klazz)
def destroy
transaction do
run_callbacks(:destroy) do
touch_paranoia_column
end
end

if callbacks_result
if ActiveRecord::VERSION::STRING >= '4.2'
each_counter_cached_associations do |association|
foreign_key = association.reflection.foreign_key.to_sym
unless destroyed_by_association && destroyed_by_association.foreign_key.to_sym == foreign_key
if send(association.reflection.name)
association.decrement_counters
result = touch_paranoia_column
if result && ActiveRecord::VERSION::STRING >= '4.2'
each_counter_cached_associations do |association|
foreign_key = association.reflection.foreign_key.to_sym
unless destroyed_by_association && destroyed_by_association.foreign_key.to_sym == foreign_key
if send(association.reflection.name)
association.decrement_counters
end
end
end
end
result
end
self
else
false
end
end

Expand Down
42 changes: 42 additions & 0 deletions test/paranoia_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,19 @@ def test_counter_cache_column_update_on_destroy#_and_restore_and_really_destroy
# assert_equal 0, parent_model_with_counter_cache_column.reload.related_models_count
end

def test_callbacks_for_counter_cache_column_update_on_destroy
parent_model_with_counter_cache_column = ParentModelWithCounterCacheColumn.create
related_model = parent_model_with_counter_cache_column.related_models.create

assert_equal nil, related_model.instance_variable_get(:@after_destroy_callback_called)
assert_equal nil, related_model.instance_variable_get(:@after_commit_on_destroy_callback_called)

related_model.destroy

assert related_model.instance_variable_get(:@after_destroy_callback_called)
assert related_model.instance_variable_get(:@after_commit_on_destroy_callback_called)
end

# TODO: find a fix for Rails 4.1
if ActiveRecord::VERSION::STRING !~ /\A4\.1/
def test_counter_cache_column_update_on_really_destroy
Expand All @@ -788,6 +801,22 @@ def test_counter_cache_column_update_on_really_destroy
end
end

# TODO: find a fix for Rails 4.0 and 4.1
if ActiveRecord::VERSION::STRING >= '4.2'
def test_callbacks_for_counter_cache_column_update_on_really_destroy!
parent_model_with_counter_cache_column = ParentModelWithCounterCacheColumn.create
related_model = parent_model_with_counter_cache_column.related_models.create

assert_equal nil, related_model.instance_variable_get(:@after_destroy_callback_called)
assert_equal nil, related_model.instance_variable_get(:@after_commit_on_destroy_callback_called)

related_model.really_destroy!

assert related_model.instance_variable_get(:@after_destroy_callback_called)
assert related_model.instance_variable_get(:@after_commit_on_destroy_callback_called)
end
end

private
def get_featureful_model
FeaturefulModel.new(:name => "not empty")
Expand Down Expand Up @@ -852,6 +881,19 @@ class RelatedModel < ActiveRecord::Base
acts_as_paranoid
belongs_to :parent_model
belongs_to :parent_model_with_counter_cache_column, counter_cache: true

after_destroy do |model|
if parent_model_with_counter_cache_column && parent_model_with_counter_cache_column.reload.related_models_count == 0
model.instance_variable_set :@after_destroy_callback_called, true
end
end
after_commit :set_after_commit_on_destroy_callback_called, on: :destroy

def set_after_commit_on_destroy_callback_called
if parent_model_with_counter_cache_column && parent_model_with_counter_cache_column.reload.related_models_count == 0
self.instance_variable_set :@after_commit_on_destroy_callback_called, true
end
end
end

class Employer < ActiveRecord::Base
Expand Down

0 comments on commit 46d9970

Please sign in to comment.