As shown in that stackoverflow answer, having no support for cascading (cascading deletes in particular) in Waterline there is a workaround for one-to-many associations by using the afterDestroy
(or afterUpdate
for soft-delete) lifecycle callback and deleting the associated records with a second query. This is possible via ManyModel.destroy({ oneModel: _.pluck(destroyedOneModels, "id") })
from within afterDestroy
.
How do we do that for a many-to-many relationship (having in mind that a junction table is used internally and we have to delete records from it)?
I did some tests using the Pet
/ User
example from the documentation with sails 0.11.
Writting this lifecycle callback in the Pet
model deletes all the users
associated to a pet
before deleting it.
// models/Pet.js
module.exports = {
attributes: {
name:'string',
color:'string',
owners: {
collection: 'user',
via: 'pets'
}
},
beforeDestroy: function(criteria, cb) {
// Destroy any user associated to a deleted pet
Pet.find(criteria).populate('owners').exec(function (err, pets){
if (err) return cb(err);
pets.forEach(function(recordToDestroy) {
User.destroy({id: _.pluck(recordToDestroy.owners, 'id')}).exec(function(err) {
console.log('The users associated to the pet ' + recordToDestroy.name + ' have been deleted');
});
});
cb();
})
}
};
I couldn't do it in the afterDestroy
lifecycle callback because the many-to-many properties of the deleted records are missing there.
Waterline is deleting the records of the junction table automatically.
The problem with this feature is that it probably would delete too much things if some pets share some owners. Following the example of the documentation, if you delete the pet Rainbow Dash, you will delete the users Mike, Cody and Gabe, and the pets Pinkie Pie and Applejack would be orphans.
If you define a many-to-many relation like this one but you know that the pets cannot have any owner in common, then it works fine. Otherwise, you should add a test to check that you will not make another pet an orphan.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With