Created
January 7, 2016 11:52
-
-
Save CjS77/44b2f75c0ec468f590d0 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
/* 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 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 | |
relation.modelTo.find({where: filter}).then(function (items) { | |
Q.all( | |
lazy(items).map(function (inst) { | |
return inst.destroy(); | |
}).toArray() | |
).then(function (results) { | |
log("Cascaded delete of: ", results); | |
if (relation.modelThrough) { | |
breakLinks(relation.modelThrough, filter, next); | |
} else { | |
next(); | |
} | |
}).catch(function (err) { | |
next(err); | |
}); | |
}); | |
} | |
}); | |
}); | |
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