Relaciones
Builders
Sección titulada «Builders»jsorm usa builders de relaciones explícitos que describen la relación SQL exacta entre dos modelos. Cada builder genera el SQL de join y mutación apropiado sin eager loading oculto ni lazy proxies.
Builders de relaciones
Sección titulada «Builders de relaciones»| Builder | Relación SQL | Cuándo usar |
|---|---|---|
t.belongsTo(Model) | Foreign key en esta tabla | User tiene columna roleId |
t.hasOne(Model) | Foreign key en otra tabla | Profile tiene columna userId |
t.hasMany(Model) | Foreign key en otra tabla | Post tiene columna authorId |
t.manyToMany(Model) | Tabla de unión | Posts ↔ Tags via post_tags |
Ejemplo
Sección titulada «Ejemplo»import { defineModel, t } from "jsorm";
/* * Usa lazy model resolvers (() => Model) * para soportar de forma segura relaciones circulares e inversas. */
export const Role = defineModel("roles", { id: t.number().primary(), name: t.string().unique(),
// one role → many users users: t.hasMany(() => User),});
export const Profile = defineModel("profiles", { id: t.number().primary(), bio: t.string().optional(),
// one profile → belongs to one user user: t.belongsTo(() => User, { constraintName: "fk_profiles_user_id", onUpdate: "cascade", onDelete: "cascade", }).index(),});
export const Tag = defineModel("tags", { id: t.number().primary(), name: t.string().unique(),
// many tags ↔ many posts posts: t.manyToMany(() => Post),});
export const Post = defineModel("posts", { id: t.number().primary(), title: t.string(),
// many posts ↔ many tags tags: t.manyToMany(() => Tag),
// many posts → one user user: t.belongsTo(() => User, { constraintName: "fk_posts_user_id", onUpdate: "cascade", onDelete: "set null", }).index(),});
export const User = defineModel("users", { id: t.number().primary(), name: t.string(),
// many users → one role role: t.belongsTo(() => Role, { constraintName: "fk_users_role_id", onUpdate: "cascade", onDelete: "restrict", }).index(),
// one user → one profile profile: t.hasOne(() => Profile),
// one user → many posts posts: t.hasMany(() => Post),});Seleccionar relaciones
Sección titulada «Seleccionar relaciones»Incluye relaciones en select para cargarlas como objetos anidados:
const users = await jsorm.get(User, { select: { id: true, name: true, role: { name: true }, profile: { bio: true }, posts: { title: true, tags: { name: true }, }, },});// Tipado: Array<{ id: number; name: string; role: { name: string }; ... }>Filtrar a través de relaciones
Sección titulada «Filtrar a través de relaciones»Usa where anidado para filtrar por campos de relaciones:
const admins = await jsorm.get(User, { select: { name: true }, where: { role: { name: { eq: 'admin' } }, posts: { title: { contains: 'release' } }, },});Mutaciones de relaciones
Sección titulada «Mutaciones de relaciones»Conectar a un registro existente
Sección titulada «Conectar a un registro existente»await jsorm.update(User, { data: { role: { connect: 1 }, }, where: { id: 5 },});Crear y conectar
Sección titulada «Crear y conectar»await jsorm.update(User, { data: { profile: { create: { bio: 'Builder from Day 1' }, }, }, where: { id: 5 },});Many-to-many connect y disconnect
Sección titulada «Many-to-many connect y disconnect»await jsorm.update(Post, { data: { tags: { connect: [1, 2, 3], disconnect: [4], }, }, where: { id: 10 },});Ejemplo completo con mutación mixta
Sección titulada «Ejemplo completo con mutación mixta»await jsorm.insert(User, { name: 'Alice', role: { connect: 1 }, profile: { create: { bio: 'Builder' }, }, posts: { create: [ { title: 'First post', tags: { connect: [1, 2] } }, ], },});Opciones de integridad referencial
Sección titulada «Opciones de integridad referencial»Configura onUpdate y onDelete en belongsTo para controlar la integridad referencial a nivel de base de datos:
role: t.belongsTo(Role, { onUpdate: 'cascade', // 'cascade' | 'restrict' | 'set-null' | 'no-action' onDelete: 'restrict',}),Buenas prácticas
Sección titulada «Buenas prácticas»- Usa el builder de relación que coincida con la forma real de los datos — no uses
hasManycuando la relación esmanyToMany. - Configura
onUpdateyonDeleteintencionalmente en lugar de depender de los defaults de la base de datos. - Mantén las mutaciones de relaciones cerca de las operaciones de escritura en lugar de dispersar la lógica de pivot manualmente.
- Siempre incluye campos de relaciones explícitamente en
select— jsorm nunca carga relaciones implícitamente.