| 
									
										
										
										
											2018-05-08 18:44:47 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Module dependencies | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Public node modules.
 | 
					
						
							|  |  |  | const _ = require('lodash'); | 
					
						
							| 
									
										
										
										
											2019-03-26 17:59:06 +01:00
										 |  |  | const mongoose = require('mongoose'); | 
					
						
							| 
									
										
										
										
											2018-05-08 18:44:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 12:19:33 +02:00
										 |  |  | // Utils
 | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  | const { | 
					
						
							|  |  |  |   models: { getValuePrimaryKey }, | 
					
						
							|  |  |  | } = require('strapi-utils'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const getModel = function(model, plugin) { | 
					
						
							|  |  |  |   return ( | 
					
						
							|  |  |  |     _.get(strapi.plugins, [plugin, 'models', model]) || | 
					
						
							|  |  |  |     _.get(strapi, ['models', model]) || | 
					
						
							|  |  |  |     undefined | 
					
						
							|  |  |  |   ); | 
					
						
							| 
									
										
										
										
											2019-03-26 17:59:06 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-28 12:13:32 +01:00
										 |  |  | const removeUndefinedKeys = obj => _.pickBy(obj, _.negate(_.isUndefined)); | 
					
						
							| 
									
										
										
										
											2018-05-08 18:44:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-28 12:13:32 +01:00
										 |  |  | module.exports = { | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |   update: async function(params) { | 
					
						
							| 
									
										
										
										
											2019-03-26 17:59:06 +01:00
										 |  |  |     const relationUpdates = []; | 
					
						
							| 
									
										
										
										
											2019-08-01 14:40:02 +02:00
										 |  |  |     const populate = this.associations.map(x => x.alias); | 
					
						
							| 
									
										
										
										
											2019-03-26 17:59:06 +01:00
										 |  |  |     const primaryKeyValue = getValuePrimaryKey(params, this.primaryKey); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |     const response = await this.findOne({ [this.primaryKey]: primaryKeyValue }) | 
					
						
							| 
									
										
										
										
											2019-03-26 17:59:06 +01:00
										 |  |  |       .populate(populate) | 
					
						
							| 
									
										
										
										
											2018-05-17 14:56:53 +02:00
										 |  |  |       .lean(); | 
					
						
							| 
									
										
										
										
											2018-05-08 18:44:47 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Only update fields which are on this document.
 | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |     const values = | 
					
						
							|  |  |  |       params.parseRelationships === false | 
					
						
							|  |  |  |         ? params.values | 
					
						
							|  |  |  |         : Object.keys(removeUndefinedKeys(params.values)).reduce( | 
					
						
							|  |  |  |             (acc, current) => { | 
					
						
							|  |  |  |               const property = params.values[current]; | 
					
						
							|  |  |  |               const association = this.associations.find( | 
					
						
							|  |  |  |                 x => x.alias === current | 
					
						
							|  |  |  |               ); | 
					
						
							|  |  |  |               const details = this._attributes[current]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               // set simple attributes
 | 
					
						
							|  |  |  |               if (!association && _.get(details, 'isVirtual') !== true) { | 
					
						
							|  |  |  |                 return _.set(acc, current, property); | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               const assocModel = getModel( | 
					
						
							|  |  |  |                 details.model || details.collection, | 
					
						
							|  |  |  |                 details.plugin | 
					
						
							|  |  |  |               ); | 
					
						
							|  |  |  |               switch (association.nature) { | 
					
						
							|  |  |  |                 case 'oneWay': { | 
					
						
							|  |  |  |                   return _.set( | 
					
						
							|  |  |  |                     acc, | 
					
						
							|  |  |  |                     current, | 
					
						
							|  |  |  |                     _.get(property, assocModel.primaryKey, property) | 
					
						
							|  |  |  |                   ); | 
					
						
							| 
									
										
										
										
											2019-03-28 12:13:32 +01:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |                 case 'oneToOne': { | 
					
						
							|  |  |  |                   // if value is the same don't do anything
 | 
					
						
							|  |  |  |                   if (response[current] === property) return acc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                   // if the value is null, set field to null on both sides
 | 
					
						
							|  |  |  |                   if (_.isNull(property)) { | 
					
						
							|  |  |  |                     const updatePromise = assocModel.updateOne( | 
					
						
							|  |  |  |                       { | 
					
						
							|  |  |  |                         [assocModel.primaryKey]: getValuePrimaryKey( | 
					
						
							|  |  |  |                           response[current], | 
					
						
							|  |  |  |                           assocModel.primaryKey | 
					
						
							|  |  |  |                         ), | 
					
						
							|  |  |  |                       }, | 
					
						
							|  |  |  |                       { [details.via]: null } | 
					
						
							|  |  |  |                     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     relationUpdates.push(updatePromise); | 
					
						
							|  |  |  |                     return _.set(acc, current, null); | 
					
						
							|  |  |  |                   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                   // set old relations to null
 | 
					
						
							|  |  |  |                   const updateLink = this.updateOne( | 
					
						
							|  |  |  |                     { [current]: new mongoose.Types.ObjectId(property) }, | 
					
						
							|  |  |  |                     { [current]: null } | 
					
						
							|  |  |  |                   ).then(() => { | 
					
						
							|  |  |  |                     return assocModel.updateOne( | 
					
						
							|  |  |  |                       { | 
					
						
							|  |  |  |                         [this.primaryKey]: new mongoose.Types.ObjectId( | 
					
						
							|  |  |  |                           property | 
					
						
							|  |  |  |                         ), | 
					
						
							|  |  |  |                       }, | 
					
						
							|  |  |  |                       { [details.via]: primaryKeyValue } | 
					
						
							|  |  |  |                     ); | 
					
						
							|  |  |  |                   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                   // set new relation
 | 
					
						
							|  |  |  |                   relationUpdates.push(updateLink); | 
					
						
							|  |  |  |                   return _.set(acc, current, property); | 
					
						
							| 
									
										
										
										
											2019-03-28 12:13:32 +01:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |                 case 'oneToMany': { | 
					
						
							|  |  |  |                   // set relation to null for all the ids not in the list
 | 
					
						
							|  |  |  |                   const currentIds = response[current]; | 
					
						
							|  |  |  |                   const toRemove = _.differenceWith( | 
					
						
							|  |  |  |                     currentIds, | 
					
						
							|  |  |  |                     property, | 
					
						
							|  |  |  |                     (a, b) => { | 
					
						
							|  |  |  |                       return ( | 
					
						
							|  |  |  |                         `${a[assocModel.primaryKey] || a}` === | 
					
						
							|  |  |  |                         `${b[assocModel.primaryKey] || b}` | 
					
						
							|  |  |  |                       ); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                   ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                   const updatePromise = assocModel | 
					
						
							|  |  |  |                     .updateMany( | 
					
						
							|  |  |  |                       { | 
					
						
							|  |  |  |                         [assocModel.primaryKey]: { | 
					
						
							|  |  |  |                           $in: toRemove.map( | 
					
						
							|  |  |  |                             val => | 
					
						
							|  |  |  |                               new mongoose.Types.ObjectId( | 
					
						
							|  |  |  |                                 val[assocModel.primaryKey] || val | 
					
						
							|  |  |  |                               ) | 
					
						
							|  |  |  |                           ), | 
					
						
							|  |  |  |                         }, | 
					
						
							|  |  |  |                       }, | 
					
						
							|  |  |  |                       { [details.via]: null } | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  |                     .then(() => { | 
					
						
							|  |  |  |                       return assocModel.updateMany( | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                           [assocModel.primaryKey]: { | 
					
						
							|  |  |  |                             $in: property.map( | 
					
						
							|  |  |  |                               val => | 
					
						
							|  |  |  |                                 new mongoose.Types.ObjectId( | 
					
						
							|  |  |  |                                   val[assocModel.primaryKey] || val | 
					
						
							|  |  |  |                                 ) | 
					
						
							|  |  |  |                             ), | 
					
						
							|  |  |  |                           }, | 
					
						
							|  |  |  |                         }, | 
					
						
							|  |  |  |                         { [details.via]: primaryKeyValue } | 
					
						
							|  |  |  |                       ); | 
					
						
							|  |  |  |                     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                   relationUpdates.push(updatePromise); | 
					
						
							|  |  |  |                   return acc; | 
					
						
							| 
									
										
										
										
											2019-03-26 17:59:06 +01:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |                 case 'manyToOne': { | 
					
						
							|  |  |  |                   return _.set( | 
					
						
							|  |  |  |                     acc, | 
					
						
							|  |  |  |                     current, | 
					
						
							|  |  |  |                     _.get(property, assocModel.primaryKey, property) | 
					
						
							|  |  |  |                   ); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 case 'manyWay': | 
					
						
							|  |  |  |                 case 'manyToMany': { | 
					
						
							|  |  |  |                   if (association.dominant) { | 
					
						
							|  |  |  |                     return _.set( | 
					
						
							|  |  |  |                       acc, | 
					
						
							|  |  |  |                       current, | 
					
						
							| 
									
										
										
										
											2019-10-01 17:56:52 +02:00
										 |  |  |                       property | 
					
						
							|  |  |  |                         ? property.map(val => val[assocModel.primaryKey] || val) | 
					
						
							|  |  |  |                         : property | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |                     ); | 
					
						
							|  |  |  |                   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                   const updatePomise = assocModel | 
					
						
							|  |  |  |                     .updateMany( | 
					
						
							|  |  |  |                       { | 
					
						
							|  |  |  |                         [assocModel.primaryKey]: { | 
					
						
							|  |  |  |                           $in: response[current].map( | 
					
						
							|  |  |  |                             val => | 
					
						
							|  |  |  |                               new mongoose.Types.ObjectId( | 
					
						
							|  |  |  |                                 val[assocModel.primaryKey] || val | 
					
						
							|  |  |  |                               ) | 
					
						
							|  |  |  |                           ), | 
					
						
							|  |  |  |                         }, | 
					
						
							|  |  |  |                       }, | 
					
						
							|  |  |  |                       { | 
					
						
							|  |  |  |                         $pull: { | 
					
						
							|  |  |  |                           [association.via]: new mongoose.Types.ObjectId( | 
					
						
							|  |  |  |                             primaryKeyValue | 
					
						
							|  |  |  |                           ), | 
					
						
							|  |  |  |                         }, | 
					
						
							|  |  |  |                       } | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  |                     .then(() => { | 
					
						
							|  |  |  |                       return assocModel.updateMany( | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                           [assocModel.primaryKey]: { | 
					
						
							| 
									
										
										
										
											2019-10-01 17:56:52 +02:00
										 |  |  |                             $in: property | 
					
						
							|  |  |  |                               ? property.map( | 
					
						
							|  |  |  |                                   val => | 
					
						
							|  |  |  |                                     new mongoose.Types.ObjectId( | 
					
						
							|  |  |  |                                       val[assocModel.primaryKey] || val | 
					
						
							|  |  |  |                                     ) | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |                                 ) | 
					
						
							| 
									
										
										
										
											2019-10-01 17:56:52 +02:00
										 |  |  |                               : property, | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |                           }, | 
					
						
							|  |  |  |                         }, | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                           $addToSet: { [association.via]: [primaryKeyValue] }, | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                       ); | 
					
						
							|  |  |  |                     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                   relationUpdates.push(updatePomise); | 
					
						
							|  |  |  |                   return acc; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 case 'manyMorphToMany': | 
					
						
							| 
									
										
										
										
											2019-08-01 14:40:02 +02:00
										 |  |  |                 case 'manyMorphToOne': { | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |                   // Update the relational array.
 | 
					
						
							|  |  |  |                   acc[current] = property.map(obj => { | 
					
						
							| 
									
										
										
										
											2019-08-01 14:40:02 +02:00
										 |  |  |                     const refModel = strapi.getModel(obj.ref, obj.source); | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |                     return { | 
					
						
							| 
									
										
										
										
											2019-08-01 14:40:02 +02:00
										 |  |  |                       ref: new mongoose.Types.ObjectId(obj.refId), | 
					
						
							| 
									
										
										
										
											2019-09-10 11:05:57 +02:00
										 |  |  |                       kind: obj.kind || refModel.globalId, | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |                       [association.filter]: obj.field, | 
					
						
							|  |  |  |                     }; | 
					
						
							|  |  |  |                   }); | 
					
						
							|  |  |  |                   break; | 
					
						
							| 
									
										
										
										
											2019-08-01 14:40:02 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |                 case 'oneToManyMorph': | 
					
						
							|  |  |  |                 case 'manyToManyMorph': { | 
					
						
							|  |  |  |                   const transformToArrayID = array => { | 
					
						
							|  |  |  |                     if (_.isArray(array)) { | 
					
						
							|  |  |  |                       return array.map(value => { | 
					
						
							|  |  |  |                         if (_.isPlainObject(value)) { | 
					
						
							|  |  |  |                           return getValuePrimaryKey(value, this.primaryKey); | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         return value; | 
					
						
							|  |  |  |                       }); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     if ( | 
					
						
							|  |  |  |                       association.type === 'model' || | 
					
						
							|  |  |  |                       (association.type === 'collection' && _.isObject(array)) | 
					
						
							|  |  |  |                     ) { | 
					
						
							|  |  |  |                       return _.isEmpty(array) | 
					
						
							|  |  |  |                         ? [] | 
					
						
							|  |  |  |                         : transformToArrayID([array]); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     return []; | 
					
						
							|  |  |  |                   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                   // Compare array of ID to find deleted files.
 | 
					
						
							|  |  |  |                   const currentValue = transformToArrayID( | 
					
						
							|  |  |  |                     response[current] | 
					
						
							|  |  |  |                   ).map(id => id.toString()); | 
					
						
							|  |  |  |                   const storedValue = transformToArrayID(property).map(id => | 
					
						
							|  |  |  |                     id.toString() | 
					
						
							|  |  |  |                   ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                   const toAdd = _.difference(storedValue, currentValue); | 
					
						
							|  |  |  |                   const toRemove = _.difference(currentValue, storedValue); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                   const model = getModel( | 
					
						
							|  |  |  |                     details.model || details.collection, | 
					
						
							|  |  |  |                     details.plugin | 
					
						
							|  |  |  |                   ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                   // Remove relations in the other side.
 | 
					
						
							|  |  |  |                   toAdd.forEach(id => { | 
					
						
							|  |  |  |                     relationUpdates.push( | 
					
						
							|  |  |  |                       module.exports.addRelationMorph.call(model, { | 
					
						
							|  |  |  |                         id, | 
					
						
							|  |  |  |                         alias: association.via, | 
					
						
							|  |  |  |                         ref: this.globalId, | 
					
						
							|  |  |  |                         refId: response._id, | 
					
						
							|  |  |  |                         field: association.alias, | 
					
						
							|  |  |  |                       }) | 
					
						
							|  |  |  |                     ); | 
					
						
							|  |  |  |                   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                   // Remove relations in the other side.
 | 
					
						
							|  |  |  |                   toRemove.forEach(id => { | 
					
						
							|  |  |  |                     relationUpdates.push( | 
					
						
							|  |  |  |                       module.exports.removeRelationMorph.call(model, { | 
					
						
							|  |  |  |                         id, | 
					
						
							|  |  |  |                         alias: association.via, | 
					
						
							|  |  |  |                         ref: this.globalId, | 
					
						
							|  |  |  |                         refId: response._id, | 
					
						
							|  |  |  |                         field: association.alias, | 
					
						
							|  |  |  |                       }) | 
					
						
							|  |  |  |                     ); | 
					
						
							|  |  |  |                   }); | 
					
						
							|  |  |  |                   break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 case 'oneMorphToOne': | 
					
						
							|  |  |  |                 case 'oneMorphToMany': | 
					
						
							|  |  |  |                   break; | 
					
						
							|  |  |  |                 default: | 
					
						
							|  |  |  |               } | 
					
						
							| 
									
										
										
										
											2019-03-26 17:59:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |               return acc; | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             {} | 
					
						
							|  |  |  |           ); | 
					
						
							| 
									
										
										
										
											2018-05-08 18:44:47 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Update virtuals fields.
 | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |     await Promise.all(relationUpdates).then(() => | 
					
						
							|  |  |  |       this.updateOne({ [this.primaryKey]: primaryKeyValue }, values, { | 
					
						
							|  |  |  |         strict: false, | 
					
						
							| 
									
										
										
										
											2018-05-08 18:44:47 +02:00
										 |  |  |       }) | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const updatedEntity = await this.findOne({ | 
					
						
							|  |  |  |       [this.primaryKey]: primaryKeyValue, | 
					
						
							|  |  |  |     }).populate(populate); | 
					
						
							| 
									
										
										
										
											2019-03-26 17:59:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-01 15:59:21 +02:00
										 |  |  |     return updatedEntity && updatedEntity.toObject | 
					
						
							|  |  |  |       ? updatedEntity.toObject() | 
					
						
							|  |  |  |       : updatedEntity; | 
					
						
							| 
									
										
										
										
											2018-05-08 18:44:47 +02:00
										 |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |   addRelationMorph: async function(params) { | 
					
						
							|  |  |  |     let entry = await this.findOne({ | 
					
						
							|  |  |  |       [this.primaryKey]: getValuePrimaryKey(params, this.primaryKey), | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2018-05-17 14:56:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (entry) { | 
					
						
							|  |  |  |       entry = entry.toJSON(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 18:44:47 +02:00
										 |  |  |     const value = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Retrieve association.
 | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |     const association = this.associations.find( | 
					
						
							|  |  |  |       association => association.alias === params.alias | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2018-05-08 18:44:47 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (!association) { | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |       throw Error( | 
					
						
							|  |  |  |         `Impossible to create relationship with ${params.ref} (${params.refId})` | 
					
						
							|  |  |  |       ); | 
					
						
							| 
									
										
										
										
											2018-05-08 18:44:47 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Resolve if the association is already existing.
 | 
					
						
							|  |  |  |     const isExisting = value.find(obj => { | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |       if ( | 
					
						
							|  |  |  |         obj.kind === params.ref && | 
					
						
							|  |  |  |         obj.ref.toString() === params.refId.toString() && | 
					
						
							|  |  |  |         obj.field === params.field | 
					
						
							|  |  |  |       ) { | 
					
						
							| 
									
										
										
										
											2018-05-08 18:44:47 +02:00
										 |  |  |         return true; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return false; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Avoid duplicate.
 | 
					
						
							|  |  |  |     if (isExisting) { | 
					
						
							|  |  |  |       return Promise.resolve(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Push new relation to the association array.
 | 
					
						
							|  |  |  |     value.push({ | 
					
						
							|  |  |  |       ref: params.ref, | 
					
						
							|  |  |  |       refId: params.refId, | 
					
						
							|  |  |  |       kind: params.ref, | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |       field: params.field, | 
					
						
							| 
									
										
										
										
											2018-05-08 18:44:47 +02:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     entry[params.alias] = value; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return module.exports.update.call(this, { | 
					
						
							|  |  |  |       id: params.id, | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |       values: entry, | 
					
						
							| 
									
										
										
										
											2018-05-08 18:44:47 +02:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |   removeRelationMorph: async function(params) { | 
					
						
							| 
									
										
										
										
											2018-05-08 18:44:47 +02:00
										 |  |  |     const entry = await this.findOne({ | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |       [this.primaryKey]: getValuePrimaryKey(params, this.primaryKey), | 
					
						
							| 
									
										
										
										
											2018-05-08 18:44:47 +02:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Filter the association array and remove the association.
 | 
					
						
							|  |  |  |     entry[params.alias] = entry[params.alias].filter(obj => { | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |       if ( | 
					
						
							|  |  |  |         obj.kind === params.ref && | 
					
						
							|  |  |  |         obj.ref.toString() === params.refId.toString() && | 
					
						
							|  |  |  |         obj.field === params.field | 
					
						
							|  |  |  |       ) { | 
					
						
							| 
									
										
										
										
											2018-05-08 18:44:47 +02:00
										 |  |  |         return false; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return module.exports.update.call(this, { | 
					
						
							|  |  |  |       id: params.id, | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |       values: entry, | 
					
						
							| 
									
										
										
										
											2018-05-08 18:44:47 +02:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2019-07-08 11:06:11 +02:00
										 |  |  |   }, | 
					
						
							| 
									
										
										
										
											2018-05-16 12:07:02 +02:00
										 |  |  | }; |