6

I have a one to many relation between Teacher(One) and Children(Many).

If I do:

Teacher.destroy(teacherId).exec(function(err){});

The children are not automatically removed.

Is it a bug or should I delete them manually? If that's not a bug, what is the explanation for not deleting children?

Zaki Aziz
  • 3,592
  • 11
  • 43
  • 61
user2867106
  • 1,139
  • 1
  • 13
  • 31

1 Answers1

16

Waterline currently doesn't support cascading deletes. It may be a configuration option in future versions, but it will probably never be the default. In most production-ready apps you probably should be doing soft-deletes anyway. In either case, you can get what you want by using the afterDestroy lifecycle callback.

In api/models/Teacher.js, something like:

module.exports = {
    attributes: {
       // attributes here
    },
    afterDestroy: function(destroyedRecords, cb) {
        // Destroy any child whose teacher has an ID of one of the 
        // deleted teacher models
        Child.destroy({teacher: _.pluck(destroyedRecords, 'id')}).exec(cb);
    }
}

You could do something similar with soft-deletes using the afterUpdate method.

sgress454
  • 24,870
  • 4
  • 74
  • 92
  • 2
    " In most production-ready apps you probably should be doing soft-deletes anyway." Please can you explain this comment further. If you have a mature (tested) ORM solution that fully supports cascading deletes (Hibernate for example) this is an expected option. Of course, care with configuration setup should be taken - that is the purpose of integration tests. If you do need to retain the history etc, then soft deletes might be appropriate but that has little to do with environment (PRD etc) and more to do with the business / technical requirements. – arcseldon Sep 23 '14 at 23:58
  • "CR" apps are another topic :D Thanks for providing some sort of workaround all the same Scott. – arcseldon Sep 24 '14 at 00:04
  • The reason soft-delete is the preferred option in production is that deletion is an expensive operation and it may impact usability if the destroyed records are big in number. Usually marking as deleted is more efficient, but it needs scoping to filter them out in all queries. In production, a nightly (or on demand) job could clean the database by actually destroying those soft-deleted. – hammady Feb 28 '16 at 15:38
  • In Sails V1.0 if you set a relationship between models e.g. `one to many` the value of the foreign property on the many table will be `NULLED` after the destroy occurs, hence results in the many objects not being destroyed. I suggest destroying the child objects in the `beforeDestory` lifecycle. – Adis Azhar Apr 26 '19 at 16:40