In general I have a goal to restrict any update of an entity if it's binded to anything.
To be specific I have two models: Order and Good. They have many-to-many relation.
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' });
I have tried to set onUpdate: 'NO ACTION' and onUpdate: 'RESTRICT' inside belongsToMany association defining but it has no effect.
Here is the code to reproduce my manipulations with goods and order
//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' });
I have no clue how to restrict it in a simple way.
Surely we always can add beforeUpdate hook on Good model but I would like to avoid this kind of complications.
I will be glad to any ideas.
As I said I was looking for simpler alternative to hooks but many researches after all led me to nowhere.
My solution was to declare the beforeUpdate hook inside Good model so inital definition
let Good = sequelize.define('good' , { name : Sequelize.STRING } );
was transformed into this
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();
}
}
})
So here we add the hook that fires every time before update particular good. It makes inner request of list of orders that contains current good.
(await instance.getOrders()).length
And depends on the result it either fire an exception if the list isn't empty or just return resolved promise that means that everything ok and current good can be updated.