The ORM supports model-level global scopes, local scopes and soft-delete filtering. These features can hide rows from a query, so document their effects in your domain layer.
Soft deletes#
Enable soft deletes on a model:
import { Model } from "@veap/database";
export class Article extends Model {
static table = "articles";
static softDeletes = true;
static deletedAtColumn = "deleted_at";
}The deleted_at column must exist in the database. By default, queries on a soft-delete model filter out rows with a non-null deleted-at value.
const visible = await Article.query().get();
const includingDeleted = await Article.withTrashed().get();
const deletedOnly = await Article.onlyTrashed().get();The exact delete/restore methods should be confirmed against the declaration for your installed package version before use.
Global scopes#
Model.addGlobalScope(name, scope) registers a named global scope. A scope can be a function or an object exposing apply; the query builder applies registered scopes when building the query.
Article.addGlobalScope("published", (query) => {
query.where("published", true);
});A global scope is appropriate for invariant filtering only when every query should inherit it. Avoid using global scopes as the only authorization mechanism.
Excluding scopes#
The query builder exposes withoutGlobalScope(name) and withoutGlobalScopes(names?). Omitting the list disables all global scopes and also includes soft-deleted rows. Use these methods narrowly and only after authorization checks.
Local scopes#
The query builder's proxy resolves a method such as active() to a model scope named scopeActive. Follow the implementation's receiver convention: the scope receives the query builder as its first argument, followed by any scope parameters.
export class Article extends Model {
static table = "articles";
static scopePublished(query: any) {
query.where("published", true);
}
}
const rows = await Article.query().published().get();Because the local-scope mechanism is dynamically dispatched, compile this pattern against your installed declarations and include it in integration tests.