The database package exports relation helpers and types for common relational patterns. Relationship methods describe how models are connected; they do not replace foreign keys or indexes in the database schema.
One-to-many#
import { Model, belongsTo, hasMany } from "@veap/database";
import type { BelongsTo, HasMany } from "@veap/database";
export class Author extends Model {
static table = "authors";
declare name: string;
posts(): HasMany<Post> {
return hasMany(this, Post, "author_id");
}
}
export class Post extends Model {
static table = "posts";
declare author_id: string;
declare title: string;
author(): BelongsTo<Author> {
return belongsTo(this, Author, "author_id");
}
}Create authors and posts tables in migrations and add a foreign key from posts.author_id to authors.id when appropriate.
Available relation types#
The inspected exports include BelongsTo, HasMany, HasOne, BelongsToMany, MorphTo, MorphMany, MorphOne, MorphToMany, and MorphedByMany, with helpers re-exported from the relations entry point. Polymorphic relationships require a schema convention for type and identifier columns; define that convention explicitly in your migrations.
Eager loading#
The query builder supports eager loading through .with(...) in the documented API. Use it when a page needs related records and you want to avoid one query per row. Verify relation names and nested loading syntax against the installed version.
const posts = await Post.query().with("author").get();Avoid N+1 queries#
Fetch the relations needed by the use case in one query plan, paginate large collections, and avoid loading full relation graphs when only a count or a few fields are required. Measure actual SQL for critical pages.