mirror of
https://github.com/strapi/strapi.git
synced 2025-07-24 17:40:18 +00:00
120 lines
3.7 KiB
JavaScript
120 lines
3.7 KiB
JavaScript
'use strict';
|
|
|
|
/**
|
|
* Module dependencies
|
|
*/
|
|
|
|
// Public node modules.
|
|
const _ = require('lodash');
|
|
|
|
// Local utils.
|
|
const actionUtil = require('../actionUtil');
|
|
const associationUtil = require('../associationUtil');
|
|
|
|
/**
|
|
* Destroy an entry
|
|
*/
|
|
|
|
module.exports = function update(_ctx) {
|
|
const deferred = Promise.defer();
|
|
|
|
// Return the model used.
|
|
const Model = actionUtil.parseModel(_ctx);
|
|
|
|
// Locate and validate the required `id` parameter.
|
|
const pk = actionUtil.requirePk(_ctx);
|
|
|
|
// Parse the values of the record to update.
|
|
const values = actionUtil.parseValues(_ctx);
|
|
|
|
// No matter what, don't allow changing the `pk` via the update blueprint
|
|
// (you should just drop and re-add the record if that's what you really want).
|
|
if (typeof values[Model.primaryKey] !== 'undefined' && values[Model.primaryKey] !== pk) {
|
|
strapi.log.warn('Cannot change primary key via update action; ignoring value sent for `' + Model.primaryKey + '`');
|
|
}
|
|
|
|
// Make sure the primary key is unchanged.
|
|
values[Model.primaryKey] = pk;
|
|
|
|
Model.findOne(pk).exec(function found(err, matchingRecord) {
|
|
if (err) {
|
|
_ctx.status = 500;
|
|
return deferred.reject(err);
|
|
}
|
|
if (!matchingRecord) {
|
|
_ctx.status = 404;
|
|
return deferred.reject('Record not found');
|
|
}
|
|
|
|
// Associations validation.
|
|
const associationsValidationPromises = [];
|
|
|
|
// One way associations.
|
|
_.forEach(_.where(Model.associations, {nature: 'oneWay'}), function (association) {
|
|
if (values[association.alias] || association.required) {
|
|
associationsValidationPromises.push(associationUtil.doesRecordExist(association.model, values[association.alias]));
|
|
}
|
|
});
|
|
|
|
// One to one associations.
|
|
_.forEach(_.where(Model.associations, {nature: 'oneToOne'}), function (association) {
|
|
if (values[association.alias] || association.required) {
|
|
associationsValidationPromises.push(associationUtil.doesRecordExist(association.model, values[association.alias]));
|
|
}
|
|
});
|
|
|
|
// Check relations params.
|
|
Promise.all(associationsValidationPromises)
|
|
.then(function () {
|
|
|
|
Model.update(pk, values).exec(function updated(err, records) {
|
|
if (err) {
|
|
_ctx.status = 400;
|
|
return deferred.reject(err);
|
|
}
|
|
|
|
// Select the first and only one record.
|
|
const updatedRecord = records[0];
|
|
|
|
// Update `oneToOneRelations`.
|
|
const relationPromises = [];
|
|
_.forEach(_.where(Model.associations, {nature: 'oneToOne'}), function (relation) {
|
|
relationPromises.push(associationUtil.oneToOneRelationUpdated(_ctx.model || _ctx.params.model, pk, relation.model, updatedRecord[relation.alias]));
|
|
});
|
|
|
|
// Update the related records.
|
|
Promise.all(relationPromises)
|
|
.then(function () {
|
|
|
|
// Extra query to find and populate the updated record.
|
|
let query = Model.findOne(updatedRecord[Model.primaryKey]);
|
|
query = actionUtil.populateEach(query, _ctx, Model);
|
|
|
|
query.exec(function foundAgain(err, populatedRecord) {
|
|
if (err) {
|
|
_ctx.status = 500;
|
|
return deferred.reject(err);
|
|
}
|
|
|
|
deferred.resolve(populatedRecord);
|
|
});
|
|
})
|
|
|
|
// Error during related records update.
|
|
.catch(function (err) {
|
|
_ctx.status = 400;
|
|
deferred.reject(err);
|
|
});
|
|
});
|
|
})
|
|
|
|
// Error during the new related records check.
|
|
.catch(function (err) {
|
|
_ctx.status = 400;
|
|
deferred.reject(err);
|
|
});
|
|
});
|
|
|
|
return deferred.promise;
|
|
};
|