Estou tendo dificuldade ao salvar um registro numa tabela de relacionamento usando o sequelize.
O tipo de relacionamento é many to many e pelo que eu aprendi, ao criar esse tipo de associação o sequelize cria alguns métodos para usar no relacionamento.
Um deles é o de adicionar um model a outro.
Ex:
{ model1.belongsToMany(model2, …)
model2.belongsToMany(model1, …) }
Seria possível usar o método { model1.addModel2(model2) }
Meu controller:
async store(req, res) {
// :usuario_id passado na url como paramentro é "2"
const { usuario_id } = req.params;
const { descricao, data } = req.body;
const usuario = await Usuario.findByPk(usuario_id);
if (!usuario) {
return res.status(400).json({ error: "Usuario responsável não encontrado" });
};
// A tabela eventos está vazia e deveria criar um evento com id "1"
const [ evento ] = await Evento.findOrCreate({
where: {
descricao,
data,
}
});
await evento.addUsuario(usuario);
return res.json(evento);
},
O erro que estou relatando ocorre apenas quando vou usar esse método, e pelo que eu percebi a query gerada está invertendo a ordem dos IDs dos models que passo para ele.
Executing (default): SELECT "created_at" AS "createdAt", "updated_at" AS "updatedAt", "evento_id", "usuario_id" FROM "usuario_eventos" AS "usuario_eventos" WHERE "usuario_eventos"."usuario_id" = 1 AND "usuario_eventos"."evento_id" IN (2);
Executing (default): INSERT INTO "usuario_eventos" ("created_at","updated_at","evento_id","usuario_id") VALUES ('2020-02-25 18:39:15.157 +00:00','2020-02-25 18:39:15.157 +00:00',2,1)
RETURNING *;
(node:11148) UnhandledPromiseRejectionWarning: SequelizeForeignKeyConstraintError: insert or update on table "usuario_eventos" violates foreign key constraint "usuario_eventos_evento_id_fkey"
Gostaria de saber o que estou fazendo de errado ou se é possível forçar a ordem correta que será passada na query.
Migration:
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('usuario_eventos', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
evento_id: {
type: Sequelize.INTEGER,
allowNull: false,
references: { model: 'eventos', key: 'id' },
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
usuario_id: {
type: Sequelize.INTEGER,
allowNull: false,
references: { model: 'usuarios', key: 'id' },
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
},
updated_at: {
type: Sequelize.DATE,
allowNull: false,
},
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('usuario_eventos');
}
};
Model Usuario:
const { Model, DataTypes } = require('sequelize');
class Usuario extends Model {
static init(sequelize) {
super.init({
nome: DataTypes.STRING,
nascimento: DataTypes.DATE,
email: DataTypes.STRING,
telefone: DataTypes.STRING,
}, {
sequelize,
})
}
static associate(models) {
this.belongsTo(models.Ministerio, { foreignKey: 'ministerio_id', as: 'ministerio' });
this.belongsToMany(models.Evento, {
foreignKey: 'evento_id',
through: 'usuario_eventos',
as: 'eventos',
})
}
}
module.exports = Usuario;
Model Evento:
const { Model, DataTypes } = require('sequelize');
class Usuario extends Model {
static init(sequelize) {
super.init({
nome: DataTypes.STRING,
nascimento: DataTypes.DATE,
email: DataTypes.STRING,
telefone: DataTypes.STRING,
}, {
sequelize,
})
}
static associate(models) {
this.belongsTo(models.Ministerio, { foreignKey: 'ministerio_id', as: 'ministerio' });
this.belongsToMany(models.Evento, {
foreignKey: 'evento_id',
through: 'usuario_eventos',
as: 'eventos',
})
}
}
module.exports = Usuario;