mirror of
				https://github.com/strapi/strapi.git
				synced 2025-11-04 03:43:34 +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;
 | 
						|
};
 |