Skip to content

paginateModel — eager-loading pagination ​

Imported from the facade: import { paginateModel } from "@/framework/facade.js".

Pagination backed by relational eager loading via db.query.table.findMany({ with }) — returns fetched relations alongside paged rows. See Database.

Signature ​

FunctionSignatureDescription
paginateModel(context, options) => Promise<PaginatedResult<T>>Relational eager loading via db.query.table.findMany({ with }) — context is the request (c on Hono, req on Express)

Options:

OptionTypeDescription
tableTableThe Drizzle table (for building count clauses)
querydb.query.<table>The relation query builder
whereSQL/booleanFilter clause
withobjectRelation tree for eager loading (nested allowed)
columnsobjectColumn selection
orderBySQL / SQL[]Sort order for the query results
perPagenumberItems per page (default 15)
pathstringBase path for pagination URLs (default c.req.path / req.path)

Use cases ​

With a relation tree ​

ts
import { desc } from "drizzle-orm";
import { db, paginateModel } from "@/framework/facade.js";

const result = await paginateModel(c, {
  table: users,
  query: db.query.users,
  where: eq(users.status, "1"),
  with: { role: true, profile: true }, // nested eager loading works too
  orderBy: desc(users.id),
  perPage: 10,
  path: c.req.path, // Hono — use req.path on Express
});
ts
import { desc } from "drizzle-orm";
import { db, paginateModel } from "@/framework/facade.js";

const result = await paginateModel(req, {
  table: users,
  query: db.query.users,
  where: eq(users.status, "1"),
  with: { role: true, profile: true }, // nested eager loading works too
  orderBy: desc(users.id),
  perPage: 10,
  path: req.path, // Express
});

Real world — deep nested relations ​

The entity module composes the full option surface in one call — with relation objects built per role, plus where, columns, orderBy, and path:

ts
// modules/project/controllers/project.controller.ts (simplified)
const result = await paginateModel(c, {
  // Hono — pass req on Express
  table: projects,
  query: db.query.projects,
  where: and(eq(projects.status, "1"), roleFilter),
  with: { departments: { with: { teams: true } }, users: true },
  columns: { hidden: false },
  orderBy: desc(projects.id),
  perPage: 15,
});
ts
// modules/project/controllers/project.controller.ts (simplified)
const result = await paginateModel(req, {
  // Hono — pass req on Express
  table: projects,
  query: db.query.projects,
  where: and(eq(projects.status, "1"), roleFilter),
  with: { departments: { with: { teams: true } }, users: true },
  columns: { hidden: false },
  orderBy: desc(projects.id),
  perPage: 15,
});

Notes ​

  • Uses the same PaginatedResult shape as paginate — see that page for the type.
  • Prefer paginateModel when the client needs the full object graph in one request; prefer paginate for flat rows with joins/aggregates.

Released under the MIT License.