mirror of
https://github.com/strapi/strapi.git
synced 2026-05-03 16:22:30 +00:00
Fix morph populate
This commit is contained in:
+1
-1
@@ -4,5 +4,5 @@
|
||||
"target": "es6"
|
||||
},
|
||||
"include": ["packages/**/*"],
|
||||
"exclude": ["node_modules", "**/node_modules/*"]
|
||||
"exclude": ["**/node_modules/*"]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const { has, pipe, prop, pick } = require('lodash/fp');
|
||||
const { pipe, prop, pick } = require('lodash/fp');
|
||||
const { MANY_RELATIONS } = require('@strapi/utils').relations.constants;
|
||||
const { setCreatorFields } = require('@strapi/utils');
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ describe('Content-Manager', () => {
|
||||
expect(strapi.entityService.update).toBeCalledWith(uid, entity.id, {
|
||||
data: { published_at: expect.any(Date) },
|
||||
params: {
|
||||
populate: [],
|
||||
populate: {},
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -63,7 +63,7 @@ describe('Content-Manager', () => {
|
||||
expect(strapi.entityService.update).toHaveBeenCalledWith(uid, entity.id, {
|
||||
data: { published_at: null },
|
||||
params: {
|
||||
populate: [],
|
||||
populate: {},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -61,6 +61,10 @@ const getDeepPopulate = (uid, populate, depth = 0) => {
|
||||
};
|
||||
}
|
||||
|
||||
if (attribute.type === 'media') {
|
||||
populateAcc[attributeName] = true;
|
||||
}
|
||||
|
||||
if (attribute.type === 'dynamiczone') {
|
||||
populateAcc[attributeName] = {
|
||||
populate: (attribute.components || []).reduce((acc, componentUID) => {
|
||||
@@ -82,7 +86,9 @@ const getBasePopulate = (uid, populate) => {
|
||||
const { attributes } = strapi.getModel(uid);
|
||||
|
||||
return Object.keys(attributes).filter(attributeName => {
|
||||
return ['relation', 'component', 'dynamiczone'].includes(attributes[attributeName].type);
|
||||
return ['relation', 'component', 'dynamiczone', 'media'].includes(
|
||||
attributes[attributeName].type
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -121,7 +127,7 @@ module.exports = {
|
||||
},
|
||||
|
||||
async findOne(id, uid, populate) {
|
||||
const params = { populate: getBasePopulate(uid, populate) };
|
||||
const params = { populate: getDeepPopulate(uid, populate) };
|
||||
|
||||
return strapi.entityService.findOne(uid, id, { params });
|
||||
},
|
||||
@@ -144,7 +150,7 @@ module.exports = {
|
||||
publishData[PUBLISHED_AT_ATTRIBUTE] = null;
|
||||
}
|
||||
|
||||
const params = { populate: getBasePopulate(uid) };
|
||||
const params = { populate: getDeepPopulate(uid) };
|
||||
|
||||
return strapi.entityService.create(uid, { params, data: publishData });
|
||||
},
|
||||
@@ -152,13 +158,13 @@ module.exports = {
|
||||
update(entity, body, uid) {
|
||||
const publishData = omitPublishedAtField(body);
|
||||
|
||||
const params = { populate: getBasePopulate(uid) };
|
||||
const params = { populate: getDeepPopulate(uid) };
|
||||
|
||||
return strapi.entityService.update(uid, entity.id, { params, data: publishData });
|
||||
},
|
||||
|
||||
delete(entity, uid) {
|
||||
const params = { populate: getBasePopulate(uid) };
|
||||
const params = { populate: getDeepPopulate(uid) };
|
||||
|
||||
return strapi.entityService.delete(uid, entity.id, { params });
|
||||
},
|
||||
@@ -180,7 +186,7 @@ module.exports = {
|
||||
|
||||
const data = { [PUBLISHED_AT_ATTRIBUTE]: new Date() };
|
||||
|
||||
const params = { populate: getBasePopulate(uid) };
|
||||
const params = { populate: getDeepPopulate(uid) };
|
||||
|
||||
return strapi.entityService.update(uid, entity.id, { params, data });
|
||||
}),
|
||||
@@ -192,7 +198,7 @@ module.exports = {
|
||||
|
||||
const data = { [PUBLISHED_AT_ATTRIBUTE]: null };
|
||||
|
||||
const params = { populate: getBasePopulate(uid) };
|
||||
const params = { populate: getDeepPopulate(uid) };
|
||||
|
||||
return strapi.entityService.update(uid, entity.id, { params, data });
|
||||
}),
|
||||
|
||||
@@ -53,13 +53,24 @@ const toRow = (metadata, data = {}) => {
|
||||
|
||||
const value = data[attributeName];
|
||||
|
||||
if (value === null) {
|
||||
Object.assign(obj, {
|
||||
[idColumn.name]: null,
|
||||
[typeColumn.name]: null,
|
||||
});
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!_.isUndefined(value)) {
|
||||
if (!_.has('id', value) || !_.has(typeField, value)) {
|
||||
throw new Error(`Expects properties ${typeField} an id to make a morph association`);
|
||||
}
|
||||
|
||||
obj[idColumn.name] = value.id;
|
||||
obj[typeColumn.name] = value[typeField];
|
||||
Object.assign(obj, {
|
||||
[idColumn.name]: value.id,
|
||||
[typeColumn.name]: value[typeField],
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -280,7 +291,7 @@ const createEntityManager = db => {
|
||||
.update({ [idColumn.name]: id, [typeColumn.name]: uid })
|
||||
.where({ id: data[attributeName] })
|
||||
.execute();
|
||||
} else if (targetAttribute.type === 'morphToMany') {
|
||||
} else if (targetAttribute.relation === 'morphToMany') {
|
||||
const { joinTable } = targetAttribute;
|
||||
const { joinColumn, morphColumn } = joinTable;
|
||||
|
||||
@@ -426,17 +437,6 @@ const createEntityManager = db => {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
if morphOne | morphMany
|
||||
clear previous:
|
||||
if morphBy is morphToOne
|
||||
set null
|
||||
set new
|
||||
|
||||
if morphBy is morphToMany
|
||||
delete links
|
||||
add links
|
||||
*/
|
||||
if (attribute.relation === 'morphOne' || attribute.relation === 'morphMany') {
|
||||
const { target, morphBy } = attribute;
|
||||
|
||||
@@ -451,11 +451,13 @@ const createEntityManager = db => {
|
||||
.where({ [idColumn.name]: id, [typeColumn.name]: uid })
|
||||
.execute();
|
||||
|
||||
await this.createQueryBuilder(target)
|
||||
.update({ [idColumn.name]: id, [typeColumn.name]: uid })
|
||||
.where({ id: data[attributeName] })
|
||||
.execute();
|
||||
} else if (targetAttribute.type === 'morphToMany') {
|
||||
if (!_.isNull(data[attributeName])) {
|
||||
await this.createQueryBuilder(target)
|
||||
.update({ [idColumn.name]: id, [typeColumn.name]: uid })
|
||||
.where({ id: data[attributeName] })
|
||||
.execute();
|
||||
}
|
||||
} else if (targetAttribute.relation === 'morphToMany') {
|
||||
const { joinTable } = targetAttribute;
|
||||
const { joinColumn, morphColumn } = joinTable;
|
||||
|
||||
@@ -470,7 +472,7 @@ const createEntityManager = db => {
|
||||
})
|
||||
.execute();
|
||||
|
||||
const rows = _.castArray(data[attributeName]).map((dataID, idx) => ({
|
||||
const rows = _.castArray(data[attributeName] || []).map((dataID, idx) => ({
|
||||
[joinColumn.name]: dataID,
|
||||
[idColumn.name]: id,
|
||||
[typeColumn.name]: uid,
|
||||
@@ -490,21 +492,11 @@ const createEntityManager = db => {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
if morphToOne
|
||||
set new values in morph columns
|
||||
*/
|
||||
if (attribute.relation === 'morphToOne') {
|
||||
// do nothing
|
||||
// handled on the entry itself
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
if morphToMany
|
||||
delete old links
|
||||
create new links
|
||||
|
||||
*/
|
||||
if (attribute.relation === 'morphToMany') {
|
||||
const { joinTable } = attribute;
|
||||
const { joinColumn, morphColumn } = joinTable;
|
||||
@@ -519,7 +511,7 @@ const createEntityManager = db => {
|
||||
})
|
||||
.execute();
|
||||
|
||||
const rows = _.castArray(data[attributeName]).map((data, idx) => ({
|
||||
const rows = _.castArray(data[attributeName] || []).map((data, idx) => ({
|
||||
[joinColumn.name]: id,
|
||||
[idColumn.name]: data.id,
|
||||
[typeColumn.name]: data[typeField],
|
||||
@@ -577,13 +569,13 @@ const createEntityManager = db => {
|
||||
if (['oneToOne', 'oneToMany'].includes(attribute.relation)) {
|
||||
await this.createQueryBuilder(joinTable.name)
|
||||
.delete()
|
||||
.where({ [inverseJoinColumn.name]: _.castArray(data[attributeName]) })
|
||||
.where({ [inverseJoinColumn.name]: _.castArray(data[attributeName] || []) })
|
||||
.where(joinTable.on || {})
|
||||
.execute();
|
||||
}
|
||||
|
||||
if (!_.isNull(data[attributeName])) {
|
||||
const insert = _.castArray(data[attributeName]).map(datum => {
|
||||
const insert = _.castArray(data[attributeName] || []).map(datum => {
|
||||
return {
|
||||
[joinColumn.name]: id,
|
||||
[inverseJoinColumn.name]: datum,
|
||||
@@ -644,7 +636,7 @@ const createEntityManager = db => {
|
||||
.update({ [idColumn.name]: null, [typeColumn.name]: null })
|
||||
.where({ [idColumn.name]: id, [typeColumn.name]: uid })
|
||||
.execute();
|
||||
} else if (targetAttribute.type === 'morphToMany') {
|
||||
} else if (targetAttribute.relation === 'morphToMany') {
|
||||
const { joinTable } = targetAttribute;
|
||||
const { morphColumn } = joinTable;
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ const createManyToMany = (attributeName, attribute, meta, metadata) => {
|
||||
* @param {ModelMetadata} meta
|
||||
* @param {Metadata} metadata
|
||||
*/
|
||||
const createMorphToOne = (attributeName, attribute, meta, metadata) => {
|
||||
const createMorphToOne = (attributeName, attribute /*meta, metadata*/) => {
|
||||
const idColumnName = 'target_id';
|
||||
const typeColumnName = 'target_type';
|
||||
|
||||
@@ -344,7 +344,7 @@ const createJoinColum = (metadata, { attribute, attributeName /*meta */ }) => {
|
||||
|
||||
if (isBidirectional(attribute)) {
|
||||
const inverseAttribute = targetMeta.attributes[attribute.inversedBy];
|
||||
// TODO: do not invert here but invert in the query ? => means we need to use owner info in the query layer
|
||||
|
||||
Object.assign(inverseAttribute, {
|
||||
joinColumn: {
|
||||
name: joinColumn.referencedColumn,
|
||||
|
||||
@@ -799,7 +799,7 @@ const applyPopulate = async (results, populate, ctx) => {
|
||||
});
|
||||
|
||||
continue;
|
||||
} else if (attribute.relation in ['morphOne', 'morphMany']) {
|
||||
} else if (['morphOne', 'morphMany'].includes(attribute.relation)) {
|
||||
const { target, morphBy } = attribute;
|
||||
|
||||
const targetAttribute = db.metadata.get(target).attributes[morphBy];
|
||||
@@ -849,7 +849,7 @@ const applyPopulate = async (results, populate, ctx) => {
|
||||
|
||||
if (_.isEmpty(referencedValues)) {
|
||||
results.forEach(result => {
|
||||
result[key] = [];
|
||||
result[key] = attribute.relation === 'morphOne' ? null : [];
|
||||
});
|
||||
|
||||
continue;
|
||||
|
||||
@@ -56,6 +56,7 @@ const createTable = meta => {
|
||||
// NOTE: we could pass uniquness for oneToOne to avoid creating more than one to one
|
||||
|
||||
const { name: columnName, referencedColumn, referencedTable } = attribute.joinColumn;
|
||||
|
||||
table.columns.push(
|
||||
createColumn(columnName, {
|
||||
type: 'integer',
|
||||
|
||||
@@ -6,7 +6,7 @@ const transformAttribute = attribute => {
|
||||
// TODO: handle a filter on field
|
||||
return {
|
||||
type: 'relation',
|
||||
relation: attribute.single === true ? 'morphOne' : 'morphMany',
|
||||
relation: attribute.multiple === true ? 'morphMany' : 'morphOne',
|
||||
target: 'plugins::upload.file',
|
||||
morphBy: 'related',
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user