JCC Express

JCC Eloquent ORM

Scopes

Introduction

JCC-Eloquent supports:

  • local scopes using scopeX methods on a model
  • global scopes using the ScopedBy([...]) decorator

Both are applied through the query builder used by Model.query().


Local scopes

Define local scopes as static methods prefixed with scope.

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

export class User extends Model {
  static scopeActive(query: Builder) {
    query.where("status", "active");
  }

  static scopeRole(query: Builder, role: string) {
    query.where("role", role);
  }
}

Use them fluently without the scope prefix:

TypeScript
const users = await User.query().active().role("admin").get();

Global scopes with ScopedBy

Create a scope class that implements Scope.

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

export class ActiveUsersScope implements Scope {
  apply(builder: Builder, model: typeof Model) {
    builder.where("status", "active");
  }
}

Attach it to your model:

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

@ScopedBy([ActiveUsersScope])
export class User extends Model {}

You can also pass a function scope:

TypeScript
@ScopedBy([
  (query) => {
    query.whereNull("deleted_at");
  },
])
export class User extends Model {}

How scope resolution works

  • Global scopes are read from model metadata via getGlobalScopes()
  • Builder applies global scopes when setModel(...) runs
  • Local scopes are resolved dynamically as scope${StudlyName} methods

Scope removal

withoutGlobalScopes(...) exists on the builder, but currently acts as a placeholder and does not remove applied scopes.

Use global scopes with that current behavior in mind.