seaorm-soft-delete
Soft-delete support for SeaORM entities.
Instead of DELETE, soft-deleted records have deleted_at set to the current timestamp.
Queries exclude soft-deleted records by default.
Installation
[]
= "0.1"
If you don't need the migration helper, disable the default feature:
= { = "0.1", = false }
Setup
1. Add deleted_at column via migration
use SoftDeleteMigration;
// inside your MigrationTrait::up()
add_column.await?;
Note: Uses
ADD COLUMN IF NOT EXISTS— idempotent on PostgreSQL only. On MySQL/SQLite, guard the migration yourself.
2. Implement SoftDeleteEntity on your entity
use SoftDeleteEntity;
3. Implement SoftDeleteActiveModel on your active model
use SoftDeleteActiveModel;
use Set;
4. Implement SoftDeleteModel on your model (optional)
Adds is_deleted() directly on model instances.
use SoftDeleteModel;
Querying
// Active records only (WHERE deleted_at IS NULL) — use by default
find_active.all.await?;
find_active_by_id.one.await?;
// Soft-deleted records only (WHERE deleted_at IS NOT NULL)
find_deleted.all.await?;
find_deleted_by_id.one.await?;
// All records including soft-deleted
find_with_deleted.all.await?;
All return Select<Entity> — chain .filter(), .order_by(), .paginate() etc. normally.
Write operations
let model: ActiveModel = user.into;
// Soft-delete: sets deleted_at = NOW()
model.soft_delete.await?;
// Restore: sets deleted_at = NULL
model.restore.await?;
// Hard delete: permanently removes the row
model.hard_delete.await?;
Checking deleted state
// Requires SoftDeleteModel impl (see Setup step 4)
if user.is_deleted
Performance tip
For large tables, add a partial index so active-record queries stay fast:
(id) WHERE deleted_at IS NULL;
MSRV
Rust 1.85+
Out of scope (v1)
- Cascading soft deletes
- Custom column names (always
deleted_at) - MySQL/SQLite idempotent migration
License
MIT