Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sails.js/Waterline cascading delete for a many-to-many association

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)?

like image 443
Radko Dinev Avatar asked Dec 23 '14 16:12

Radko Dinev


1 Answers

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.

like image 127
Alexis N-o Avatar answered Oct 03 '22 09:10

Alexis N-o