Soft Deletes

Mark records as deleted without permanently removing them from the database

What are Soft Deletes?

Soft deletes allow you to mark records as deleted without actually removing them from the database. This is useful for maintaining data integrity, implementing undo functionality, or keeping records for audit purposes.

Enabling Soft Deletes

Enable soft deletes on a model by setting the softDelete option:

models/post.tstypescript
import { defineModel, DataTypes } from "stabilize-orm";
export const Post = defineModel({
tableName: "posts",
softDelete: true, // Enable soft deletes
columns: {
id: {
type: DataTypes.Integer,
},
title: {
type: DataTypes.String,
length: 255,
},
content: {
type: DataTypes.Text,
},
},
});

When enabled, Stabilize automatically adds a deletedAt column to your table.

Soft Deleting Records

Use the standard delete method - it will automatically perform a soft delete:

const repo = orm.getRepository(Post);
// Soft delete a post (sets deletedAt to current timestamp)
await repo.delete(1);
// The record still exists in the database
// but won't appear in normal queries

Restoring Soft Deleted Records

Restore a soft deleted record using the recover method:

const repo = orm.getRepository(Post);
// Restore a soft deleted post
await repo.recover(1);
// The post is now available in normal queries again
const post = await repo.findById(1);
console.log(post); // Post is restored
// Bulk restore
await repo.recover([1, 2, 3]);

Permanent Deletion

Force a permanent deletion using the forceDelete method:

const repo = orm.getRepository(Post);
// Permanently delete a post (removes from database)
await repo.forceDelete(1);
// This cannot be undone!

Query Builder Integration

Soft delete filters work seamlessly with the query builder:

const repo = orm.getRepository(Post);
// Complex query excluding soft deleted
const posts = await repo
.query()
.where("published", "=", true)
.orderBy("createdAt", "DESC")
.limit(10)
.findAll();

Best Practices

  • Use soft deletes for user-generated content that might need to be restored
  • Implement a cleanup job to permanently delete old soft-deleted records
  • Consider the storage implications of keeping deleted records
  • Add indexes on the deletedAt column for better query performance
  • Document which models use soft deletes in your team's guidelines