-
Notifications
You must be signed in to change notification settings - Fork 2k
/
remove.js
93 lines (71 loc) · 3.33 KB
/
remove.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/**
* Module dependencies
*/
var _ = require('@sailshq/lodash');
var formatUsageError = require('../formatUsageError');
/**
* Remove a member from an association
*
* http://sailsjs.com/docs/reference/blueprint-api/remove-from
*
*/
module.exports = function remove(req, res) {
var parseBlueprintOptions = req.options.parseBlueprintOptions || req._sails.config.blueprints.parseBlueprintOptions;
// Set the blueprint action for parseBlueprintOptions.
req.options.blueprintAction = 'remove';
var queryOptions = parseBlueprintOptions(req);
var Model = req._sails.models[queryOptions.using];
var relation = queryOptions.alias;
// The primary key of the parent record
var parentPk = queryOptions.targetRecordId;
// Get the model class of the child in order to figure out the name of
// the primary key attribute.
var associationAttr = _.findWhere(Model.associations, { alias: relation });
var ChildModel = req._sails.models[associationAttr.collection];
// The primary key of the child record;
var childPk = queryOptions.associatedIds[0];
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// FUTURE: Use a database transaction here, if all of the involved models
// are using the same datastore, and if that datastore supports transactions.
// e.g.
// ```
// Model.getDatastore().transaction(function during(db, proceed){ ... })
// .exec(function afterwards(err, result){}));
// ```
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Model.findOne(parentPk).meta(queryOptions.meta).exec(function foundParent(err, parentRecord) {
if (err) { return res.serverError(err); }
if (!parentRecord) { return res.notFound(); }
// Look up the child record to make sure it exists.
ChildModel.findOne(childPk).exec(function foundChild(err, childRecord) {
if (err) { return res.serverError(err); }
// No such child record? Bail out with a 404.
if (!childRecord) {return res.notFound();}
Model.removeFromCollection(parentPk, relation, childPk).exec(function(err) {
if (err) {
// If this is a usage error coming back from Waterline,
// (e.g. a bad criteria), then respond w/ a 400 status code.
// Otherwise, it's something unexpected, so use 500.
switch (err.name) {
case 'UsageError': return res.badRequest(formatUsageError(err, req));
default: return res.serverError(err);
}
}//-•
// Finally, look up the parent record again and populate the relevant collection.
var query = Model.findOne(parentPk, queryOptions.populates).meta(queryOptions.meta);
query.exec(function found(err, parentRecord) {
if (err) { return res.serverError(err); }
if (!parentRecord) { return res.serverError(); }
if (!parentRecord[relation]) { return res.serverError(); }
if (!parentRecord[Model.primaryKey]) { return res.serverError(); }
// If we have the pubsub hook, use the model class's publish method
// to notify all subscribers about the removed item
if (req._sails.hooks.pubsub) {
Model._publishRemove(parentRecord[Model.primaryKey], relation, childPk, !req._sails.config.blueprints.mirror && req);
}
return res.ok(parentRecord);
});
});
});
});
};