Relations Overview
Define relationships between models — oneToOne, oneToMany, manyToOne, and manyToMany
Chainable API
VibORM uses a chainable API for defining relations:
s.manyToOne(() => targetModel).fields("fk").references("id")
The thunk () => targetModel comes first to handle circular references between models, then configuration methods are chained.
Relation Types
| Relation | Description | Example |
|---|---|---|
s.oneToOne() |
One record relates to one other | User → Profile |
s.oneToMany() |
One record relates to many | User → Posts |
s.manyToOne() |
Many records relate to one | Post → Author |
s.manyToMany() |
Many relate to many | Post ↔ Tags |
Quick Example
import { s } from "viborm";
const user = s.model({
id: s.string().id().ulid(),
email: s.string().unique(),
profile: s.oneToOne(() => profile).optional(),
posts: s.oneToMany(() => post),
});
const profile = s.model({
id: s.string().id().ulid(),
bio: s.string(),
userId: s.string().unique(),
user: s.oneToOne(() => user)
.fields("userId")
.references("id"),
});
const post = s.model({
id: s.string().id().ulid(),
title: s.string(),
authorId: s.string(),
author: s.manyToOne(() => user)
.fields("authorId")
.references("id"),
tags: s.manyToMany(() => tag),
});
const tag = s.model({
id: s.string().id().ulid(),
name: s.string().unique(),
posts: s.manyToMany(() => post),
});
Methods by Relation Type
ToOne Relations (oneToOne, manyToOne)
s.manyToOne(() => target)
.fields("authorId") // FK field on current model
.references("id") // Referenced field on target model
.optional() // Mark as optional (FK can be null)
.onDelete("cascade") // Referential action on delete
.onUpdate("cascade") // Referential action on update
.name("author") // Custom relation name
ToMany Relations (oneToMany)
s.oneToMany(() => target)
.name("posts") // Custom relation name (only method needed)
The FK configuration is done on the manyToOne side, not here.
ManyToMany Relations
s.manyToMany(() => target)
.through("post_tags") // Junction table name
.A("postId") // Source FK in junction table
.B("tagId") // Target FK in junction table
.onDelete("cascade") // Referential action (applies to both FKs)
.onUpdate("cascade") // Referential action (applies to both FKs)
.name("tags") // Custom relation name
Referential Actions
.onDelete() and .onUpdate() accept one of four actions:
| Action | Description |
|---|---|
cascade |
Delete/update related records |
setNull |
Set FK to NULL (requires nullable FK and .optional()) |
restrict |
Prevent delete/update if related records exist |
noAction |
Database default behavior |
This is the canonical reference — the per-relation pages link back here.