Query Scopes
Reusable query filters for cleaner, more maintainable code
Define Scopes
Scopes are defined in the scopes property of your model config. Each scope receives the QueryBuilder and optional parameters:
models/User.ts
import { defineModel, DataTypes } from "stabilize-orm";
const User = defineModel({ tableName: "users", columns: { id: { type: DataTypes.STRING, required: true, unique: true }, email: { type: DataTypes.STRING, length: 255, required: true }, name: { type: DataTypes.STRING, length: 100 }, isActive: { type: DataTypes.BOOLEAN, defaultValue: true }, role: { type: DataTypes.STRING, length: 50, defaultValue: "user" }, }, scopes: { active: (qb) => qb.where("isActive = ?", true), inactive: (qb) => qb.where("isActive = ?", false), admin: (qb) => qb.where("role = ?", "admin"), byRole: (qb, role: string) => qb.where("role = ?", role), recent: (qb, days: number) => qb.where( "createdAt >= ?", new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString() ), },});Use Scopes
Apply scopes via the scope() method on the repository or query builder:
examples/use-scopes.ts
const userRepo = orm.getRepository(User);
// Single scopeconst activeUsers = await userRepo .scope("active") .execute(orm.client);
// Chain multiple scopesconst activeAdmins = await userRepo .scope("active") .scope("admin") .execute(orm.client);
// Scope with parametersconst editors = await userRepo .scope("byRole", "editor") .execute(orm.client);
// Recent users (last 7 days)const recentUsers = await userRepo .scope("recent", 7) .execute(orm.client);
// Combine scopes with other query methodsconst recentActiveAdmins = await userRepo .scope("active") .scope("admin") .scope("recent", 30) .orderBy("createdAt", "DESC") .limit(10) .execute(orm.client);Scopes with Soft Deletes
The find() method automatically filters out soft-deleted records. Scopes work within this filter:
examples/scope-soft-delete.ts
// Automatically excludes soft-deleted recordsconst activePosts = await postRepo .scope("published") .execute(orm.client);
// Find soft-deleted recordsconst deletedPosts = await postRepo .findDeleted() .execute(orm.client);
// Find all records including soft-deletedconst allPosts = await postRepo .withTrashed() .execute(orm.client);