Relations Overview
Hysteria ORM supports rich relation types between models:
belongsTo
hasOne
hasMany
manyToMany
Relations are retrieved using batch loading, so one query is made for each relation only if load
is called.
Be carefull, too many relation retrieve could slow down you overall query
Annotations and nested relations are typed inside the retrieved relations.
Example Models
class User extends Model {
@hasMany(() => Post, 'userId')
declare posts: Post[];
@manyToMany(() => Address, () => UserAddress, {
leftForeignKey: 'userId',
rightForeignKey: 'addressId',
})
declare addresses: Address[];
}
class Post extends Model {
@belongsTo(() => User, 'userId')
declare user: User;
}
class Address extends Model {
@manyToMany(() => User, () => UserAddress, {
leftForeignKey: 'addressId',
rightForeignKey: 'userId',
})
declare users: User[];
}
Querying Relations
- Remember to always select the foreign key in the relation query builder, otherwise the relation will not be filled.
Eager Loading
const users = await User.query().load('posts').many();
Selecting columns
In this case userId
must be selected in the relation query builder, otherwise the relation will not be filled.
const users = await User.query().load('posts', (qb) =>
qb.select('id', 'title', 'userId')
).many();
Nested Relations
const users = await User.query().load('posts', (qb) =>
qb.load('user')
).many();
Filtering on Relations
const users = await User.query().load('posts', (qb) =>
qb.where('title', 'Hello World')
).many();
Limiting and Offset
Limiting and offset are referred to the related models, so in this case 10 posts will be selected for each user skipping the first 10.
Adding limit
or offset
will create a CTE to apply the limit and offset to the related models.
const users = await User.query().load('posts', (qb) =>
qb.where('title', 'Hello World').limit(10).offset(10)
).many();
Advanced relation queries
const users = await User.query().load('posts', (qb) =>
qb.annotate("max", "id", "maxId").load("user")
).many();
Best Practices
- Use
load
for batch relation loading. - Use callbacks for nested and filtered relations.
- Always define foreign keys explicitly for clarity.
Next: Advanced SQL Features