JCC Express

JCC Eloquent ORM

SoftDelete

Introduction

JCC-Eloquent supports soft deletes using a deleted_at column.

When soft deletes are enabled on a model:

  • deleting a model sets deleted_at instead of removing the row
  • default queries exclude rows where deleted_at is not null
  • you can include or isolate trashed rows with query helpers

Enable soft deletes on a model

TypeScript
import { Model } from "jcc-express-mvc/Eloquent";

export class User extends Model {
  protected softDeletes = true;
}

Soft deletes are disabled by default (softDeletes = false).


Add the deleted_at column in migration

Use the schema helper:

TypeScript
import { Schema } from "jcc-express-mvc/Eloquent";

await Schema.create("users", (table) => {
  table.id();
  table.string("name");
  table.softDeletes(); // adds deleted_at
  table.timestamps();
});

Querying trashed and non-trashed rows

Use model query helpers:

TypeScript
// Non-trashed only (default)
const activeUsers = await User.query().get();

// Include both trashed and non-trashed
const allUsers = await User.withTrashed().get();

// Only trashed
const trashedUsers = await User.onlyTrashed().get();

Deleting and restoring

Instance delete and restore

TypeScript
const user = await User.find(1);

if (user) {
  await user.delete();   // sets deleted_at when softDeletes is true
  await user.restore();  // sets deleted_at back to null, then saves
}

Bulk restore

TypeScript
await User.onlyTrashed().where("role", "guest").restore();

Event behavior with soft deletes

Soft-deleting still triggers model lifecycle events:

  • deleting before setting deleted_at
  • deleted after the update
  • restoring and restored around restore flow

Use deleteQuietly() if you need to skip events on an instance.