From 35fbb6dfe890294237238883328c67dac2675304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20=C5=A0im=C3=A1nek?= Date: Sun, 19 Jul 2026 01:35:13 +0200 Subject: [PATCH] Restore soft-deleted dependents on recursive restore restore_relations read dependents under the default scope, so soft-deleted children were skipped when the parent was reloaded before restoring. Read them unscoped. Supersedes #30. Co-authored-by: KouyaFukuda --- lib/mongoid/paranoia.rb | 8 ++++---- spec/mongoid/paranoia_spec.rb | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/mongoid/paranoia.rb b/lib/mongoid/paranoia.rb index 279d714..dfc7141 100644 --- a/lib/mongoid/paranoia.rb +++ b/lib/mongoid/paranoia.rb @@ -162,10 +162,10 @@ def to_param def restore_relations relations.each_pair do |name, association| next unless association.dependent == :destroy - relation = send(name) - next unless relation.present? && relation.paranoid? - Array.wrap(relation).each do |doc| - doc.restore(recursive: true) + klass = association.klass + documents = klass ? klass.unscoped { Array.wrap(send(name)) } : Array.wrap(send(name)) + documents.each do |doc| + doc.restore(recursive: true) if doc.respond_to?(:restore) end end end diff --git a/spec/mongoid/paranoia_spec.rb b/spec/mongoid/paranoia_spec.rb index f8a5003..158ee2d 100644 --- a/spec/mongoid/paranoia_spec.rb +++ b/spec/mongoid/paranoia_spec.rb @@ -856,6 +856,20 @@ class ParanoidConfiguredReset it { expect{ subject.restore_relations}.to_not change { NormHasMany.count } } it { expect{ subject.restore_relations}.to_not change { NormHabtm.count } } end + + context "when the parent is reloaded before restoring (regression for #30)" do + before { subject.destroy } + + it "restores soft-deleted has_many dependents" do + reloaded = ParaBase.unscoped.find(subject.id) + expect { reloaded.restore(recursive: true) }.to change { ParaHasMany.count }.by(2) + end + + it "restores soft-deleted has_one dependents" do + reloaded = ParaBase.unscoped.find(subject.id) + expect { reloaded.restore(recursive: true) }.to change { ParaHasOne.count }.by(1) + end + end end describe ".scoped" do