Skip to main content

Usage Guides

1) Runtime setup

  1. Configure .env.
  2. Set DB_CONNECTION.
  3. Register models at startup:
registerModels([User, Post, ...]);
or generate a bootstrap helper:
eloquent make:registry
Keep strict mode enabled by default unless you have migration-specific lazy bootstrap needs. This project is intended to run with Express.js in request/route-based applications. Use Express.js without changes to run model registration and query workflows reliably.

2) Migration workflow

eloquent make:migration User
eloquent make:migration --all --test
eloquent migrate:run --all-migrations
eloquent migrate:status

3) Seeding workflow

eloquent db:seed --class UserSeeder
eloquent db:seed --test --class BlogScenarioSeeder
eloquent db:seed:fresh --class UserSeeder --force --yes
eloquent db:seed --all-connections --class UserSeeder
eloquent db:seed:precheck --all-connections

4) Multi-driver workflow

  • Single target: --mysql, --pg, --sqlite
  • All SQL connections: --all-connections
  • Mongo target (SQL-only excluded): --mongo, --mongo --test
  • For one app talking to different drivers at once, keep one DB_CONNECTION fallback and pin static connectionName on the models that must stay on a specific driver
Example mixed runtime:
export class User extends SqlModel<UserAttrs> {
  static connectionName = "mysql";
}

export class GeoLocation extends MongoModel<GeoAttrs> {
  static connectionName = "mongo";
}
See the full contract in Multi-Connection Strategy.

5) Test mode workflow

eloquent make:model User --test
eloquent make:registry --test
eloquent make:migration --all --test
eloquent migrate:run --test --all-migrations

6) Recovery and safety

  • Use --force --yes with production guard checks for destructive operations.
  • Prefer least-privilege credentials:
    • ELOQUENT_DB_ROLE=runtime
    • ELOQUENT_DB_ROLE=migration
  • Keep CLI prechecks in place before --all-connections seed runs.
Detailed runtime guides:

7) NoSQL quick path

Use explicit target flags and keep SQL operations out of implicit scopes.
eloquent db:seed:precheck --mongo --test
eloquent make:scenario --test --mongo --run

8) Runtime querying patterns

Important: runtime querying contract

The runtime read API is Laravel-like and should stay aligned with the public CRUD contract.
  • static safe-finder helpers such as User.where(...), User.orderBy(...), User.first(), and User.findOneBy(...)
  • static primary-key reads such as User.find(id)
  • instance collection reads such as new User().all()
  • eager-loading helpers such as with(...) and load(...) when explicit relation methods exist
Recommended app-level pattern:
  1. use static query helpers for filtered reads
  2. use findOneBy(...) or first() when you want one record or null
  3. use get() when you want hydrated arrays
  4. use with(...) only when the model exposes explicit relation methods
See also:

9) Runtime CRUD patterns

Important: runtime CRUD contract

The runtime write API is intentionally split into three layers:
  • User.create(data)
    • create a new row or document
  • loaded instance methods such as update(), fill(), save(), delete(), restore(), and patch()
    • update an already loaded model instance
  • explicit low-level by-id methods such as User.updateById(id, data), User.deleteById(id), and User.restoreById(id)
    • direct writes when you already know the primary key
Recommended app-level pattern:
  1. read with query helpers
  2. update with update() + save() or patch() on a loaded instance
  3. use User.updateById(...), User.deleteById(...), and User.restoreById(...) only when you intentionally want a direct by-id service path
  4. use bulk helpers only when the service already owns a concrete list of ids or row payloads
See also:

10) Cache in read paths

Use cache at the service boundary, not in controllers.
import { CacheManager, setupCache } from "@alpha.consultings/eloquent-orm.js";

setupCache();
Production cache env keys:
APP_ENV=production
MEMCACHED_HOST=127.0.0.1
MEMCACHED_PORT=11211
CACHE_DIR=.cache
Current runtime behavior:
  • APP_ENV=development: memory cache
  • APP_ENV=staging: file cache using CACHE_DIR
  • APP_ENV=production: Memcached, then file cache, then memory cache
Read-through pattern:
async function activeUsers() {
  const key = "users:active:v1";
  const cached = await CacheManager.get(key);
  if (cached) return cached;

  const users = await User.where("is_active", true)
    .orderBy("created_at", "desc")
    .limit(20)
    .get();

  await CacheManager.set(key, users, 60);
  return users;
}
Write-through invalidation:
async function createUser(data: Record<string, unknown>) {
  const created = await User.create(data);
  await CacheManager.delete("users:active:v1");
  return created;
}
Cache operations:
eloquent cache:stats
eloquent cache:clear

11) Model implementation by driver

SQL runtime model

import { SqlModel, column, relation, type ModelInstance } from "@alpha.consultings/eloquent-orm.js";

type UserAttrs = { id?: number; name?: string };

export class User extends SqlModel<UserAttrs> {
  static tableName = "users";
  static connectionName = process.env.DB_CONNECTION ?? "mysql";
  static schema = {
    id: column("increments", undefined, { primary: true }),
    name: column("string", 255),
    posts: relation("hasMany", "Post", { foreignKey: "user_id" }),
  };

  constructor() {
    super("users", process.env.DB_CONNECTION ?? "mysql");
  }
}

export interface User extends ModelInstance<UserAttrs> {}

Mongo runtime model

import { MongoModel, column, relation, type ModelInstance } from "@alpha.consultings/eloquent-orm.js";

type GeoAttrs = { id?: number; name?: string };

export class GeoLocation extends MongoModel<GeoAttrs> {
  static tableName = "geolocations";
  static connectionName = "mongo";
  static schema = {
    id: column("increments", undefined, { primary: true }),
    name: column("string", 255),
  };

  constructor() {
    super("geolocations", "mongo");
  }
}

export interface GeoLocation extends ModelInstance<GeoAttrs> {}
Use SQL classes when you need migrations and relation constraints. Use Mongo classes when you need document-first storage and --mongo flows.