diff --git a/lib/paranoia.rb b/lib/paranoia.rb index 4ba4c389..530d6f98 100644 --- a/lib/paranoia.rb +++ b/lib/paranoia.rb @@ -69,6 +69,7 @@ def paranoia_destroy association.decrement_counters end @_disable_counter_cache = false + @_trigger_destroy_callback = true result end end @@ -183,6 +184,31 @@ def timestamp_attributes_with_current_time timestamp_attributes_for_update_in_model.each_with_object({}) { |attr,hash| hash[attr] = current_time_from_proper_timezone } end + def transaction_include_any_action?(actions) + actions.any? do |action| + case action + when :create + transaction_record_state(:new_record) + when :destroy + if ActiveRecord::VERSION::STRING < "5.1.0" + transaction_include_destroy? + else + defined?(@_trigger_destroy_callback) && @_trigger_destroy_callback + end + when :update + update_trigger = !(transaction_record_state(:new_record) || transaction_include_destroy?) + if ActiveRecord::VERSION::STRING >= "5.1.0" + update_trigger &&= (defined?(@_trigger_update_callback) && @_trigger_update_callback) + end + update_trigger + end + end + end + + def transaction_include_destroy? + destroyed? || try(:paranoia_destroyed?) + end + # restore associated records that have been soft deleted when # we called #destroy def restore_associated_records(recovery_window_range = nil) diff --git a/test/paranoia_test.rb b/test/paranoia_test.rb index e08f9a7b..4eb5cad8 100644 --- a/test/paranoia_test.rb +++ b/test/paranoia_test.rb @@ -115,6 +115,16 @@ def test_destroy_behavior_for_plain_models assert_equal 0, model.class.unscoped.count end + def test_after_commit_on_destroy_callbacks + model = AfterCommitDestroyModel.new + model.save + model.reset_after_commit_callback_called # clear called callback flags + refute model.after_commit_callback_called + model.destroy + + assert model.after_commit_callback_called + end + # Anti-regression test for #81, which would've introduced a bug to break this test. def test_destroy_behavior_for_plain_models_callbacks model = CallbackModel.new @@ -1371,3 +1381,22 @@ class ParanoidBelongsTo < ActiveRecord::Base belongs_to :paranoid_has_one end end + +class AfterCommitDestroyModel < ActiveRecord::Base + self.table_name = "callback_models" + + attr_reader :after_commit_callback_called + + acts_as_paranoid + after_commit :callback_triggered, on: :destroy + + def reset_after_commit_callback_called + @after_commit_callback_called = false + end + + private + + def callback_triggered + @after_commit_callback_called = true + end +end