dyrynda/laravel-cascade-soft-deletes
Adds cascading soft deletes to Laravel Eloquent models via a simple trait. When a parent model is soft deleted or restored, its related models are soft deleted or restored too, keeping data consistent without extra observers or manual event wiring.
$cascadeDeletes = ['tasks', 'documents']) instead of hand-writing observers per model — so the product promise ("deleting a workspace archives everything inside it; restoring brings it back") becomes cheap to ship.DELETE means "hidden but recoverable" vs "gone" is a retention/UX decision. Cascading soft deletes makes the recoverable path coherent, which is usually the difference between shipping a delete button this quarter and shipping one with a compliance review attached.forceDelete to cascade hard deletes, so the two policies can be modeled as distinct code paths rather than ad-hoc admin scripts — a decision you can defend to legal/privacy.Consider adoption when all of the following hold:
SoftDeletes broadly; the package is additive (trait + property), no schema migration, no config file.$model->delete()), not bulk query-builder statements.restoring hook re-restores everything in $cascadeDeletes, including children that were soft-deleted independently before the parent was deleted. If "undo must not resurrect a comment a moderator removed last week," you need extra bookkeeping (e.g., a deletion batch/reason column) on top.Look elsewhere, or plan to wrap it, when:
ON DELETE CASCADE or hard deletes; the package targets soft-delete graphs and won't help there.Model::where(...)->delete(), queued mass cleanup) — model events don't fire, so cascades silently don't happen. Same for raw SQL and some upsert/truncate paths.deleting event on a web request. Watch request latency and transaction size.Given Dependents: 0 on the metric and the single-maintainer profile, treat it as low-blast-radius convenience code: fine to adopt, but keep the usage surface small (trait + $cascadeDeletes array) so a fork or inline replacement is trivial. The recent 2026-03-20 release suggests it's still maintained, but pin the version and add a test that asserts cascade behavior on your critical aggregates.
For executives (30 seconds): "When a customer deletes a project, workspace, or account, the things inside it should disappear from the product too — and come back if the customer changes their mind. Today that's manual code repeated for every parent entity, and it's where 'I deleted it but it's still showing up' bugs come from. There's a small, free, MIT-licensed Laravel package that handles this in a few lines per model. Cost: roughly a day of engineering plus tests, no infrastructure change, no database migration. Risk: low and reversible — it's an isolated trait we can remove or replace without touching our schema or data. What I need from you is a decision on policy, not code: which entity deletions are archival (recoverable, retained) versus destructive (permanent erasure), because that determines how we configure it and what we tell customers and auditors."
For engineering: "Trait on the aggregate root, list relations in $cascadeDeletes; it hooks deleting/restoring and also overrides forceDelete to cascade permanent deletes. No migrations, no service provider required, MIT, pinned. Two caveats we should design around: (1) query-builder/bulk deletes bypass model events, so all delete entry points must go through model instances or an explicit service; (2) restore re-restores everything in the list, so if we need 'undo only what the parent took down,' we add a deletion-batch column now rather than retrofit later. Add feature tests per aggregate covering delete, restore, and force-delete paths before rollout."
Ask: approve the policy decision (archival vs. erasure per entity) and a one-day spike with tests on the two highest-traffic aggregates; we'll report back on cascade latency and orphan counts before widening adoption.
How can I help you explore Laravel packages today?