Fix image being unlinked from entity on entity creation

This commit is contained in:
Alexandre Bodin 2019-11-27 11:32:39 +01:00
parent 713f848f9e
commit 24e5aceb44

View File

@ -27,7 +27,7 @@ module.exports = {
const populate = this.associations.map(x => x.alias); const populate = this.associations.map(x => x.alias);
const primaryKeyValue = getValuePrimaryKey(params, this.primaryKey); const primaryKeyValue = getValuePrimaryKey(params, this.primaryKey);
const response = await this.findOne({ [this.primaryKey]: primaryKeyValue }) const entry = await this.findOne({ [this.primaryKey]: primaryKeyValue })
.populate(populate) .populate(populate)
.lean(); .lean();
@ -36,40 +36,44 @@ module.exports = {
params.parseRelationships === false params.parseRelationships === false
? params.values ? params.values
: Object.keys(removeUndefinedKeys(params.values)).reduce( : Object.keys(removeUndefinedKeys(params.values)).reduce(
(acc, current) => { (acc, attribute) => {
const property = params.values[current]; const currentValue = entry[attribute];
const newValue = params.values[attribute];
const association = this.associations.find( const association = this.associations.find(
x => x.alias === current x => x.alias === attribute
); );
const details = this._attributes[current];
const details = this._attributes[attribute];
// set simple attributes // set simple attributes
if (!association && _.get(details, 'isVirtual') !== true) { if (!association && _.get(details, 'isVirtual') !== true) {
return _.set(acc, current, property); return _.set(acc, attribute, newValue);
} }
const assocModel = getModel( const assocModel = getModel(
details.model || details.collection, details.model || details.collection,
details.plugin details.plugin
); );
switch (association.nature) { switch (association.nature) {
case 'oneWay': { case 'oneWay': {
return _.set( return _.set(
acc, acc,
current, attribute,
_.get(property, assocModel.primaryKey, property) _.get(newValue, assocModel.primaryKey, newValue)
); );
} }
case 'oneToOne': { case 'oneToOne': {
// if value is the same don't do anything // if value is the same don't do anything
if (response[current] === property) return acc; if (currentValue === newValue) return acc;
// if the value is null, set field to null on both sides // if the value is null, set field to null on both sides
if (_.isNull(property)) { if (_.isNull(newValue)) {
const updatePromise = assocModel.updateOne( const updatePromise = assocModel.updateOne(
{ {
[assocModel.primaryKey]: getValuePrimaryKey( [assocModel.primaryKey]: getValuePrimaryKey(
response[current], currentValue,
assocModel.primaryKey assocModel.primaryKey
), ),
}, },
@ -77,18 +81,18 @@ module.exports = {
); );
relationUpdates.push(updatePromise); relationUpdates.push(updatePromise);
return _.set(acc, current, null); return _.set(acc, attribute, null);
} }
// set old relations to null // set old relations to null
const updateLink = this.updateOne( const updateLink = this.updateOne(
{ [current]: new mongoose.Types.ObjectId(property) }, { [attribute]: new mongoose.Types.ObjectId(newValue) },
{ [current]: null } { [attribute]: null }
).then(() => { ).then(() => {
return assocModel.updateOne( return assocModel.updateOne(
{ {
[this.primaryKey]: new mongoose.Types.ObjectId( [this.primaryKey]: new mongoose.Types.ObjectId(
property newValue
), ),
}, },
{ [details.via]: primaryKeyValue } { [details.via]: primaryKeyValue }
@ -97,14 +101,14 @@ module.exports = {
// set new relation // set new relation
relationUpdates.push(updateLink); relationUpdates.push(updateLink);
return _.set(acc, current, property); return _.set(acc, attribute, newValue);
} }
case 'oneToMany': { case 'oneToMany': {
// set relation to null for all the ids not in the list // set relation to null for all the ids not in the list
const currentIds = response[current]; const attributeIds = currentValue;
const toRemove = _.differenceWith( const toRemove = _.differenceWith(
currentIds, attributeIds,
property, newValue,
(a, b) => { (a, b) => {
return ( return (
`${a[assocModel.primaryKey] || a}` === `${a[assocModel.primaryKey] || a}` ===
@ -131,7 +135,7 @@ module.exports = {
return assocModel.updateMany( return assocModel.updateMany(
{ {
[assocModel.primaryKey]: { [assocModel.primaryKey]: {
$in: property.map( $in: newValue.map(
val => val =>
new mongoose.Types.ObjectId( new mongoose.Types.ObjectId(
val[assocModel.primaryKey] || val val[assocModel.primaryKey] || val
@ -149,8 +153,8 @@ module.exports = {
case 'manyToOne': { case 'manyToOne': {
return _.set( return _.set(
acc, acc,
current, attribute,
_.get(property, assocModel.primaryKey, property) _.get(newValue, assocModel.primaryKey, newValue)
); );
} }
case 'manyWay': case 'manyWay':
@ -158,10 +162,10 @@ module.exports = {
if (association.dominant) { if (association.dominant) {
return _.set( return _.set(
acc, acc,
current, attribute,
property newValue
? property.map(val => val[assocModel.primaryKey] || val) ? newValue.map(val => val[assocModel.primaryKey] || val)
: property : newValue
); );
} }
@ -169,7 +173,7 @@ module.exports = {
.updateMany( .updateMany(
{ {
[assocModel.primaryKey]: { [assocModel.primaryKey]: {
$in: response[current].map( $in: currentValue.map(
val => val =>
new mongoose.Types.ObjectId( new mongoose.Types.ObjectId(
val[assocModel.primaryKey] || val val[assocModel.primaryKey] || val
@ -189,14 +193,14 @@ module.exports = {
return assocModel.updateMany( return assocModel.updateMany(
{ {
[assocModel.primaryKey]: { [assocModel.primaryKey]: {
$in: property $in: newValue
? property.map( ? newValue.map(
val => val =>
new mongoose.Types.ObjectId( new mongoose.Types.ObjectId(
val[assocModel.primaryKey] || val val[assocModel.primaryKey] || val
) )
) )
: property, : newValue,
}, },
}, },
{ {
@ -211,8 +215,9 @@ module.exports = {
case 'manyMorphToMany': case 'manyMorphToMany':
case 'manyMorphToOne': { case 'manyMorphToOne': {
// Update the relational array. // Update the relational array.
acc[current] = property.map(obj => { acc[attribute] = newValue.map(obj => {
const refModel = strapi.getModel(obj.ref, obj.source); const refModel = strapi.getModel(obj.ref, obj.source);
return { return {
ref: new mongoose.Types.ObjectId(obj.refId), ref: new mongoose.Types.ObjectId(obj.refId),
kind: obj.kind || refModel.globalId, kind: obj.kind || refModel.globalId,
@ -247,15 +252,15 @@ module.exports = {
}; };
// Compare array of ID to find deleted files. // Compare array of ID to find deleted files.
const currentValue = transformToArrayID( const attributeValue = transformToArrayID(currentValue).map(
response[current] id => id.toString()
).map(id => id.toString()); );
const storedValue = transformToArrayID(property).map(id => const storedValue = transformToArrayID(newValue).map(id =>
id.toString() id.toString()
); );
const toAdd = _.difference(storedValue, currentValue); const toAdd = _.difference(storedValue, attributeValue);
const toRemove = _.difference(currentValue, storedValue); const toRemove = _.difference(attributeValue, storedValue);
const model = getModel( const model = getModel(
details.model || details.collection, details.model || details.collection,
@ -269,8 +274,9 @@ module.exports = {
id, id,
alias: association.via, alias: association.via,
ref: this.globalId, ref: this.globalId,
refId: response._id, refId: entry._id,
field: association.alias, field: association.alias,
filter: association.filter,
}) })
); );
}); });
@ -282,7 +288,7 @@ module.exports = {
id, id,
alias: association.via, alias: association.via,
ref: this.globalId, ref: this.globalId,
refId: response._id, refId: entry._id,
field: association.alias, field: association.alias,
}) })
); );
@ -316,30 +322,21 @@ module.exports = {
: updatedEntity; : updatedEntity;
}, },
addRelationMorph: async function(params) { async addRelationMorph(params) {
const { alias, id } = params;
let entry = await this.findOne({ let entry = await this.findOne({
[this.primaryKey]: getValuePrimaryKey(params, this.primaryKey), [this.primaryKey]: id,
}); });
if (entry) { if (!entry) {
entry = entry.toJSON(); throw new Error(
} `Relation ${params.field} cannot be created because the target entity doesnt exist`
const value = [];
// Retrieve association.
const association = this.associations.find(
association => association.alias === params.alias
);
if (!association) {
throw Error(
`Impossible to create relationship with ${params.ref} (${params.refId})`
); );
} }
// Resolve if the association is already existing. // if association already exists ignore
const isExisting = value.find(obj => { const relationExists = entry[alias].find(obj => {
if ( if (
obj.kind === params.ref && obj.kind === params.ref &&
obj.ref.toString() === params.refId.toString() && obj.ref.toString() === params.refId.toString() &&
@ -351,34 +348,28 @@ module.exports = {
return false; return false;
}); });
// Avoid duplicate. if (relationExists) return Promise.resolve();
if (isExisting) {
return Promise.resolve();
}
// Push new relation to the association array. entry[alias].push({
value.push({ ref: new mongoose.Types.ObjectId(params.refId),
ref: params.ref,
refId: params.refId,
kind: params.ref, kind: params.ref,
field: params.field, [params.filter]: params.field,
}); });
entry[params.alias] = value; await entry.save();
return module.exports.update.call(this, {
id: params.id,
values: entry,
});
}, },
removeRelationMorph: async function(params) { async removeRelationMorph(params) {
const { alias, id } = params;
const entry = await this.findOne({ const entry = await this.findOne({
[this.primaryKey]: getValuePrimaryKey(params, this.primaryKey), [this.primaryKey]: id,
}); });
if (!entry) return Promise.resolve();
// Filter the association array and remove the association. // Filter the association array and remove the association.
entry[params.alias] = entry[params.alias].filter(obj => { entry[alias] = entry[alias].filter(obj => {
if ( if (
obj.kind === params.ref && obj.kind === params.ref &&
obj.ref.toString() === params.refId.toString() && obj.ref.toString() === params.refId.toString() &&
@ -390,9 +381,6 @@ module.exports = {
return true; return true;
}); });
return module.exports.update.call(this, { entry.save();
id: params.id,
values: entry,
});
}, },
}; };