-
-
Save Alexisvt/92d55c19ace0bd31823597d44cdf14ae to your computer and use it in GitHub Desktop.
Loopback cascade mixin gist
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Cascade delete for loopback | |
// https://gist.github.com/CjS77/44b2f75c0ec468f590d0 | |
/* jshint node:true */ | |
'use strict'; | |
/** | |
* There is an incubating feature to cascade the deletes to the relational tables. see | |
* https://github.com/strongloop/loopback-datasource-juggler/issues/88 | |
*/ | |
var lazy = require('lazy.js'); | |
var async = require('async'); | |
var log = require('debug')('mixins:cascade'); | |
var Q = require('q'); | |
module.exports = function (Model, options) { | |
var matchRelation = function (name) { | |
return lazy(Model.relations).find(function (mr) { | |
return mr.name === name; | |
}); | |
}; | |
//Pre-process and remove unsupported relations | |
lazy(options).keys().forEach(function (relationName) { | |
var relation = matchRelation(relationName); | |
if (relation && relation.type === 'referencesMany') { | |
log("Cascading to referencesMany is not supported - %s", relation.name); | |
delete options[relationName]; | |
} | |
}); | |
Model.observe('after delete', function (ctx, next) { | |
if (!(ctx.instance || ctx.where)) { | |
log("There is no way to apply cascading deletes on a multi-record delete"); | |
return; //Nothing we can do | |
} | |
var promises = []; | |
var thisId = ctx.instance ? ctx.instance.id : ctx.where.id; | |
lazy(options).keys().each(function (relationName) { | |
var relation = matchRelation(relationName); | |
if (!relation) { | |
return; | |
} | |
var filter = {}; | |
filter[relation.keyTo] = thisId; | |
if (options[relationName].unlink) { | |
var throughModel = relation.modelThrough; | |
if (throughModel) { | |
breakLinks(throughModel, filter, next); | |
} else { | |
log("%s.%s does not have a through model. Nothing to unlink", Model.definition.name, relationName); | |
} | |
} else { | |
//See https://gist.github.com/fabien/126ccfaca48ddf1cefb8 | |
var promise = relation.modelTo.find({where: filter}).then(function (items) { | |
return Q.all( | |
lazy(items).map(function (inst) { | |
return inst.destroy(); | |
}).toArray() | |
).then(function (results) { | |
log("Cascaded delete of: ", items); | |
if (relation.modelThrough) { | |
breakLinks(relation.modelThrough, filter, next); | |
} | |
}); | |
}); | |
promises.push(promise); | |
} | |
}); | |
Promise.all(promises).then(function(results) { | |
log('Cascade: ' + results); | |
next(); | |
}); | |
}); | |
function breakLinks(throughModel, filter, next) { | |
throughModel.destroyAll(filter).then(function (info) { | |
log("Removed %d links from %s referring to %s", info.count, throughModel.definition.name, Model.definition.name); | |
next(); | |
}).catch(function (err) { | |
next(err); | |
}); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment