Una asociación de uno a muchos nos permite relacionar dos modelos a través de una llave foránea, por ejemplo los modelos Person
y Car
, donde una persona puede tener cero o muchos carros, pero un auto solo puede tener un dueño.
**const { Sequelize, Datatypes } = require("sequelize");
const sequelize = new Sequelize("your URI string", {...config});
const personSchema = {
name: {
type: DataTypes.STRING,
allowNull: false,
},
id: {
type: DataTypes.INTEGER,
allowNull: false,
autoIncrement: true,
unique: true,
primaryKey: true,
}
};
const carSchema = {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false,
unique: true,
autoIncrement: true
},
ownerId {
field: "owner_id",
type: DataTypes.INTEGER,
references: {
model: "people",
key: "id"
},
onUpdate: "CASCADE",
onDelete: "SET NULL",
}
};
const Person = sequelize.define("Person", personSchema, {
tableName: "people",
timestamps: false,
});
const Car = sequelize.define("Car", personSchema, {
tableName: "cars",
timestamps: false,
});
sequelize.sync(); //también se podrían usar migraciones**
Lo que acabamos de hacer es definir los schemas para ambos modelos, donde el schema de Car
tiene un campo ownerId
que hace de llave foránea para así poder realizar la asociación entre los dos modelos. Veamos a más detalle cada propiedad de dicho campo:
field
→ le indicamos a Sequelize que la columna que se le asigne al campo ownerId
dentro de la base de datos se debe llamar owner_id
.
type
→ la llave foránea va a ser un número entero.
references
→ este es el campo más importante de todos, ya que aquí es donde se establece la referencia a la tabla con la que queremos crear la asociación. Este objeto tiene dos propiedades:
model
→ el nombre de la tabla con la que queremos crear la asociación, en este caso es people
.key
→ el campo en el cual se encuentra la llave primaria de la tabla a la cual queremos asociarnos.Recordar que el nombre de la tabla está definido en el método
sequelize.define
o enmodelName.init
si se están usando clases.
onUpdate
→indicamos qué se debería hacer si el id del dueño cambia; en este caso indicamos que si el nombre del dueño cambia, entonces su referencia en la tabla cars también debería actualizarse.
onDelete
→ indicamos qué se debería hacer si el id del dueño se elimina, mejor dicho, qué debería pasar cuando la tupla del dueño se elimine; en este caso le decimos que si la tupla del dueño se borra, entonces el valor de la referencia debería cambiar a null
.
Ahora que los modelos ya están definidos podemos empezar a crear las asociaciones entre los modelos, para que así las tablas dentro de la base de datos también se relacionen. Sequelize nos da dos métodos para crear asociaciones, ambos nos brindan el mismo resultado y las diferencias son muy pocas.
sourceModel.hasMany(targetModel, {...options})
→ representa una asociación donde el target model es el que define la llave foránea dentro de su schema.
**Person.hasMany(Car, {
foreignKey: "ownerId",
as: "car"
});**
Con esto le indicamos a Sequelize que el campo donde se encuentra la llave foránea se llama ownerId
y se encuentra en el schema del target model (Car
), además de que a esta asociación le agregamos un alias (car
) con la propiedad as
.
sourceModel.belongsTo(targetModel, {...options})
→ representa una asociación donde el source model es el que define la llave foránea dentro de su schema.
**Car.belongsTo(Person, {
foreignKey: "ownerId",
as: "owner"
});**
Con esto le indicamos a Sequelize que el campo donde se encuentra la llave foránea se llama ownerId
y se encuentra en el schema del source model (Car
), además de que a esta asociación le agregamos un alias (owner
) con la propiedad as
.
Importante!!! En el campo de
foreignKey
, que se agrega al momento de establecer la asociación, se coloca el nombre de la propiedad que se declaró en el schema, no el valor que se define enfield
.
Y con esto hecho ya tenemos las asociaciones listas y Sequelize se encargará de crear las relaciones con las tablas correspondientes.