@relation / @relationship
Declares relationships between models. Both @relation and @relationship are accepted interchangeably. See the Relations section for full concept docs.
Syntax
syntax
@relation <kind>:<Model>[;foreignKey:<col>][;relatedKey:<col>][;through:<table>][;onDelete:CASCADE|SET NULL]One-to-Many
src/interfaces.ts
interface User {
// @relation onetomany:Post;foreignKey:userId
posts?: Post[];
}
interface Post {
userId: number;
// @relation manytoone:User;foreignKey:userId
user?: User;
}One-to-One
src/interfaces.ts
interface User {
// @relationship onetoone:Profile;foreignKey:userId
profile?: Profile;
}
interface Profile {
// @unique
userId: number;
// @relationship onetoone:User;foreignKey:userId;onDelete:CASCADE
user?: User;
}Many-to-Many
src/interfaces.ts
interface User {
// @relation manytomany:Team;through:team_members;foreignKey:userId;relatedKey:teamId
teams?: Team[];
}
interface Team {
// @relation manytomany:User;through:team_members;foreignKey:teamId;relatedKey:userId
members?: User[];
}
// Pivot table team_members(userId, teamId) auto-created by migrate()Relation Shortcuts
src/interfaces.ts
// @belongsTo:Model — shortcut for manytoone
// @belongsTo:User
user?: User;
// @hasMany:Model — shortcut for onetomany
// @hasMany:Post
posts?: Post[];
// @hasOne:Model — shortcut for onetoone
// @hasOne:Profile
profile?: Profile;
// @belongsToMany:Model — shortcut for manytomany
// @belongsToMany:Team
teams?: Team[];Parameters
| Param | Required | Description |
|---|---|---|
foreignKey | Yes | Column on the child/many side |
relatedKey | Many-to-many | Column on the related side (default: id) |
through | Many-to-many | Pivot table name |
onDelete | No | CASCADE or SET NULL on foreign key |
Errors
| Error | Cause | Fix |
|---|---|---|
Post.user -> User has no inverse relation for Post | One side of a relation is missing the inverse annotation | Add @relation manytoone:Post on the inverse side |
Unknown relation target | Model name doesn't match any known interface | Check the model name spelling in the annotation |
Duplicate interface "User" found | Multiple models have the same name in different files | Use unique interface names across your project |
Conventions
- Always declare both sides of a relation (inverse) to enable preloading
- Foreign key fields should be
numbertype (orstringfor UUIDs) - Use
onDelete:CASCADEfor strong ownership;onDelete:SET NULLfor weak references - Pivot tables for many-to-many are auto-created by
migrate()— no interface needed - Relation shortcuts (
@belongsTo, etc.) are syntactic sugar and produce the same metadata
See also
- Full Relations Documentation — preloading, filtering, and traversal