En general, tengo el objetivo de restringir cualquier actualización de una entidad si está vinculada a algo.
Para ser especifico tengo dos modelos: Order y Good . Tienen una relación de muchos a muchos.
let Good = sequelize.define('good' , { name:Sequelize.STRING}); let Order = sequelize.define('order' , { }); //M:N relation Good.belongsToMany(Order, { through: 'GoodsInOrders' }); Order.belongsToMany(Good, { through: 'GoodsInOrders' }); Intenté configurar onUpdate: 'NO ACTION' y onUpdate: 'RESTRICT' dentro de la definición de asociación belongsToMany , pero no tiene ningún efecto.
Aquí está el código para reproducir mis manipulaciones con bienes y pedidos.
//creating few goods let good1 = await Good.create({ name:'Coca-Cola' }); let good2 = await Good.create({ name:'Hamburger' }); let good3 = await Good.create({ name:'Fanta' }); //creating an order let order = await Order.create(); //adding good1 and good2 to the order await order.addGoods([good1,good2]); //It's ok to update good3 since no orders contains It await good3.update( { name:'Pepsi' }); //But I need to fire an exeption if I try to update any goods belonged to order //There should be an error because we previously added good1 to order await good1.update( { name:'Sandwich' }); No tengo idea de cómo restringirlo de una manera simple.
Seguramente siempre podemos agregar beforeUpdate de actualización en Good modelo, pero me gustaría evitar este tipo de complicaciones.
Estaré encantado de cualquier idea.
Como dije, estaba buscando una alternativa más simple a los ganchos, pero muchas investigaciones después de todo no me llevaron a ninguna parte.
Mi solución fue declarar el beforeUpdate dentro del modelo Good , por lo que la definición inicial
let Good = sequelize.define('good' , { name : Sequelize.STRING } );se transformó en esto
let Good = sequelize.define('good', { name: Sequelize.STRING }, { hooks: { beforeUpdate: async (instance, options) => { if ((await instance.getOrders()).length) return Promise.reject('error'); return Promise.resolve(); } } })Así que aquí añadimos el gancho que se dispara cada vez antes de actualizar en particular. Realiza solicitud interna de listado de pedidos que contiene el bien vigente.
(await instance.getOrders()).lengthY depende del resultado, activa una excepción si la lista no está vacía o simplemente devuelve la promesa resuelta, lo que significa que todo está bien y se puede actualizar.