mirror of
https://github.com/strapi/strapi.git
synced 2025-12-25 14:14:10 +00:00
Update & delete polymorphic
This commit is contained in:
parent
6cc1c05bf9
commit
e4199664c9
@ -19,131 +19,21 @@ async function main(connection) {
|
||||
|
||||
await orm.schema.reset();
|
||||
|
||||
let res, articleA, articleB, c1, c2, f1, f2;
|
||||
let res;
|
||||
|
||||
f1 = await orm.query('folder').create({ data: {} });
|
||||
f2 = await orm.query('folder').create({ data: {} });
|
||||
|
||||
articleA = await orm.query('article').create({
|
||||
data: {
|
||||
reportables: [
|
||||
{
|
||||
__type: 'folder',
|
||||
id: f1.id,
|
||||
},
|
||||
{
|
||||
__type: 'folder',
|
||||
id: f2.id,
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
articleB = await orm.query('article').create({
|
||||
data: {
|
||||
reportables: {
|
||||
__type: 'folder',
|
||||
id: f2.id,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
res = await orm.query('folder').findMany({
|
||||
populate: {
|
||||
articles: {
|
||||
populate: {
|
||||
reportables: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
log(res);
|
||||
|
||||
// morph one
|
||||
|
||||
await orm.query('comment').create({
|
||||
data: {
|
||||
article: articleA.id,
|
||||
},
|
||||
});
|
||||
|
||||
res = await orm.query('comment').findMany({
|
||||
populate: {
|
||||
article: true,
|
||||
},
|
||||
});
|
||||
|
||||
log(res);
|
||||
|
||||
res = await orm.query('article').findMany({
|
||||
populate: {
|
||||
commentable: true,
|
||||
},
|
||||
});
|
||||
|
||||
log(res);
|
||||
// morph many
|
||||
|
||||
await orm.query('video-comment').create({
|
||||
data: {
|
||||
articles: [articleA.id, articleB.id],
|
||||
},
|
||||
});
|
||||
|
||||
res = await orm.query('video-comment').findMany({
|
||||
populate: {
|
||||
articles: true,
|
||||
},
|
||||
});
|
||||
|
||||
log(res);
|
||||
|
||||
res = await orm.query('article').findMany({
|
||||
populate: {
|
||||
commentable: true,
|
||||
},
|
||||
});
|
||||
|
||||
log(res);
|
||||
|
||||
//----------
|
||||
|
||||
c1 = await orm.query('comment').create({
|
||||
data: {
|
||||
title: 'test',
|
||||
},
|
||||
});
|
||||
|
||||
c2 = await orm.query('video-comment').create({
|
||||
const c1 = await orm.query('comment').create({
|
||||
data: {
|
||||
title: 'coucou',
|
||||
articles: [articleA.id, articleB.id],
|
||||
},
|
||||
});
|
||||
|
||||
// morph to one
|
||||
|
||||
await orm.query('article').create({
|
||||
const c2 = await orm.query('video-comment').create({
|
||||
data: {
|
||||
commentable: {
|
||||
__type: 'comment',
|
||||
id: c1.id,
|
||||
},
|
||||
title: 'coucou',
|
||||
},
|
||||
});
|
||||
|
||||
res = await orm.query('article').findMany({
|
||||
populate: {
|
||||
commentable: true,
|
||||
},
|
||||
});
|
||||
|
||||
log(res);
|
||||
|
||||
// morph to many
|
||||
|
||||
await orm.query('article').create({
|
||||
res = await orm.query('article').create({
|
||||
data: {
|
||||
dz: [
|
||||
{
|
||||
@ -156,8 +46,13 @@ async function main(connection) {
|
||||
},
|
||||
],
|
||||
},
|
||||
populate: {
|
||||
dz: true,
|
||||
},
|
||||
});
|
||||
|
||||
log(res);
|
||||
|
||||
res = await orm.query('article').findMany({
|
||||
populate: {
|
||||
dz: true,
|
||||
|
||||
@ -261,65 +261,34 @@ const createEntityManager = db => {
|
||||
for (const attributeName in attributes) {
|
||||
const attribute = attributes[attributeName];
|
||||
|
||||
if (!_.has(attributeName, data)) {
|
||||
if (attribute.type !== 'relation' || !_.has(attributeName, data)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: handle cleaning before creating the assocaitions
|
||||
switch (attribute.relation) {
|
||||
case 'morphOne':
|
||||
case 'morphMany': {
|
||||
const { target, morphBy } = attribute;
|
||||
if (attribute.relation === 'morphOne' || attribute.relation === 'morphMany') {
|
||||
const { target, morphBy } = attribute;
|
||||
|
||||
const targetAttribute = db.metadata.get(target).attributes[morphBy];
|
||||
const targetAttribute = db.metadata.get(target).attributes[morphBy];
|
||||
|
||||
if (targetAttribute.relation === 'morphToOne') {
|
||||
// set columns
|
||||
const { idColumn, typeColumn } = targetAttribute.morphColumn;
|
||||
if (targetAttribute.relation === 'morphToOne') {
|
||||
// set columns
|
||||
const { idColumn, typeColumn } = targetAttribute.morphColumn;
|
||||
|
||||
await this.createQueryBuilder(target)
|
||||
.update({ [idColumn.name]: id, [typeColumn.name]: uid })
|
||||
.where({ id: data[attributeName] })
|
||||
.execute();
|
||||
} else if (targetAttribute.type === 'morphToMany') {
|
||||
const { joinTable } = targetAttribute;
|
||||
const { name, joinColumn, morphColumn } = joinTable;
|
||||
|
||||
const { idColumn, typeColumn } = morphColumn;
|
||||
|
||||
const rows = _.castArray(data[attributeName]).map((dataID, idx) => ({
|
||||
[joinColumn.name]: dataID,
|
||||
[idColumn.name]: id,
|
||||
[typeColumn.name]: uid,
|
||||
...(joinTable.on || {}),
|
||||
order: idx,
|
||||
}));
|
||||
|
||||
if (_.isEmpty(rows)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await this.createQueryBuilder(name)
|
||||
.insert(rows)
|
||||
.execute();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
case 'morphToOne': {
|
||||
// handled on the entry itself
|
||||
continue;
|
||||
}
|
||||
case 'morphToMany': {
|
||||
const { joinTable } = attribute;
|
||||
const { name, joinColumn, morphColumn } = joinTable;
|
||||
await this.createQueryBuilder(target)
|
||||
.update({ [idColumn.name]: id, [typeColumn.name]: uid })
|
||||
.where({ id: data[attributeName] })
|
||||
.execute();
|
||||
} else if (targetAttribute.type === 'morphToMany') {
|
||||
const { joinTable } = targetAttribute;
|
||||
const { joinColumn, morphColumn } = joinTable;
|
||||
|
||||
const { idColumn, typeColumn } = morphColumn;
|
||||
|
||||
const rows = _.castArray(data[attributeName]).map((data, idx) => ({
|
||||
[joinColumn.name]: id,
|
||||
[idColumn.name]: data.id,
|
||||
[typeColumn.name]: data.__type,
|
||||
const rows = _.castArray(data[attributeName]).map((dataID, idx) => ({
|
||||
[joinColumn.name]: dataID,
|
||||
[idColumn.name]: id,
|
||||
[typeColumn.name]: uid,
|
||||
...(joinTable.on || {}),
|
||||
order: idx,
|
||||
}));
|
||||
@ -328,12 +297,38 @@ const createEntityManager = db => {
|
||||
continue;
|
||||
}
|
||||
|
||||
await this.createQueryBuilder(name)
|
||||
await this.createQueryBuilder(joinTable.name)
|
||||
.insert(rows)
|
||||
.execute();
|
||||
}
|
||||
|
||||
continue;
|
||||
} else if (attribute.relation === 'morphToOne') {
|
||||
// handled on the entry itself
|
||||
continue;
|
||||
} else if (attribute.relation === 'morphToMany') {
|
||||
const { joinTable } = attribute;
|
||||
const { joinColumn, morphColumn } = joinTable;
|
||||
|
||||
const { idColumn, typeColumn } = morphColumn;
|
||||
|
||||
const rows = _.castArray(data[attributeName]).map((data, idx) => ({
|
||||
[joinColumn.name]: id,
|
||||
[idColumn.name]: data.id,
|
||||
[typeColumn.name]: data.__type,
|
||||
...(joinTable.on || {}),
|
||||
order: idx,
|
||||
}));
|
||||
|
||||
if (_.isEmpty(rows)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await this.createQueryBuilder(joinTable.name)
|
||||
.insert(rows)
|
||||
.execute();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (attribute.joinColumn && attribute.owner) {
|
||||
@ -428,7 +423,122 @@ const createEntityManager = db => {
|
||||
for (const attributeName in attributes) {
|
||||
const attribute = attributes[attributeName];
|
||||
|
||||
if (attribute.type !== 'relation' || !_.has(attributeName, data)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: implement polymorphic
|
||||
/*
|
||||
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;
|
||||
|
||||
const targetAttribute = db.metadata.get(target).attributes[morphBy];
|
||||
|
||||
if (targetAttribute.relation === 'morphToOne') {
|
||||
// set columns
|
||||
const { idColumn, typeColumn } = targetAttribute.morphColumn;
|
||||
|
||||
await this.createQueryBuilder(target)
|
||||
.update({ [idColumn.name]: null, [typeColumn.name]: null })
|
||||
.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') {
|
||||
const { joinTable } = targetAttribute;
|
||||
const { joinColumn, morphColumn } = joinTable;
|
||||
|
||||
const { idColumn, typeColumn } = morphColumn;
|
||||
|
||||
await this.createQueryBuilder(joinTable.name)
|
||||
.delete()
|
||||
.where({
|
||||
[idColumn.name]: id,
|
||||
[typeColumn.name]: uid,
|
||||
...(joinTable.on || {}),
|
||||
})
|
||||
.execute();
|
||||
|
||||
const rows = _.castArray(data[attributeName]).map((dataID, idx) => ({
|
||||
[joinColumn.name]: dataID,
|
||||
[idColumn.name]: id,
|
||||
[typeColumn.name]: uid,
|
||||
...(joinTable.on || {}),
|
||||
order: idx,
|
||||
}));
|
||||
|
||||
if (_.isEmpty(rows)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await this.createQueryBuilder(joinTable.name)
|
||||
.insert(rows)
|
||||
.execute();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
if morphToOne
|
||||
set new values in morph columns
|
||||
*/
|
||||
if (attribute.relation === 'morphToOne') {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
if morphToMany
|
||||
delete old links
|
||||
create new links
|
||||
|
||||
*/
|
||||
if (attribute.relation === 'morphToMany') {
|
||||
const { joinTable } = attribute;
|
||||
const { joinColumn, morphColumn } = joinTable;
|
||||
|
||||
const { idColumn, typeColumn } = morphColumn;
|
||||
|
||||
await this.createQueryBuilder(joinTable.name)
|
||||
.delete()
|
||||
.where({
|
||||
[joinColumn.name]: id,
|
||||
...(joinTable.on || {}),
|
||||
})
|
||||
.execute();
|
||||
|
||||
const rows = _.castArray(data[attributeName]).map((data, idx) => ({
|
||||
[joinColumn.name]: id,
|
||||
[idColumn.name]: data.id,
|
||||
[typeColumn.name]: data.__type,
|
||||
...(joinTable.on || {}),
|
||||
order: idx,
|
||||
}));
|
||||
|
||||
if (_.isEmpty(rows)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await this.createQueryBuilder(joinTable.name)
|
||||
.insert(rows)
|
||||
.execute();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (attribute.joinColumn && attribute.owner) {
|
||||
// TODO: check edgecase
|
||||
@ -518,17 +628,84 @@ const createEntityManager = db => {
|
||||
*/
|
||||
// TODO: wrap Transaction
|
||||
async deleteRelations(uid, id) {
|
||||
// TODO: Implement correctly
|
||||
if (db.dialect.usesForeignKeys()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { attributes } = db.metadata.get(uid);
|
||||
|
||||
for (const attributeName in attributes) {
|
||||
const attribute = attributes[attributeName];
|
||||
|
||||
// TODO: implement polymorphic
|
||||
if (attribute.type !== 'relation') {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
if morphOne | morphMany
|
||||
if morphBy is morphToOne
|
||||
set null
|
||||
if morphBy is morphToOne
|
||||
delete links
|
||||
*/
|
||||
if (attribute.relation === 'morphOne' || attribute.relation === 'morphMany') {
|
||||
const { target, morphBy } = attribute;
|
||||
|
||||
const targetAttribute = db.metadata.get(target).attributes[morphBy];
|
||||
|
||||
if (targetAttribute.relation === 'morphToOne') {
|
||||
// set columns
|
||||
const { idColumn, typeColumn } = targetAttribute.morphColumn;
|
||||
|
||||
await this.createQueryBuilder(target)
|
||||
.update({ [idColumn.name]: null, [typeColumn.name]: null })
|
||||
.where({ [idColumn.name]: id, [typeColumn.name]: uid })
|
||||
.execute();
|
||||
} else if (targetAttribute.type === 'morphToMany') {
|
||||
const { joinTable } = targetAttribute;
|
||||
const { morphColumn } = joinTable;
|
||||
|
||||
const { idColumn, typeColumn } = morphColumn;
|
||||
|
||||
await this.createQueryBuilder(joinTable.name)
|
||||
.delete()
|
||||
.where({
|
||||
[idColumn.name]: id,
|
||||
[typeColumn.name]: uid,
|
||||
...(joinTable.on || {}),
|
||||
})
|
||||
.execute();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
if morphToOne
|
||||
nothing to do
|
||||
*/
|
||||
if (attribute.relation === 'morphToOne') {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
/*
|
||||
if morphToMany
|
||||
delete links
|
||||
*/
|
||||
if (attribute.relation === 'morphToMany') {
|
||||
const { joinTable } = attribute;
|
||||
const { joinColumn } = joinTable;
|
||||
|
||||
await this.createQueryBuilder(joinTable.name)
|
||||
.delete()
|
||||
.where({
|
||||
[joinColumn.name]: id,
|
||||
...(joinTable.on || {}),
|
||||
})
|
||||
.execute();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (db.dialect.usesForeignKeys()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: we do not remove existing associations with the target as it should handled by unique FKs instead
|
||||
if (attribute.joinColumn && attribute.owner) {
|
||||
|
||||
@ -140,10 +140,7 @@ const createMetadata = (models = []) => {
|
||||
}
|
||||
|
||||
if (types.isRelation(attribute.type)) {
|
||||
// NOTE: also validate
|
||||
|
||||
createRelation(attributeName, attribute, meta, metadata);
|
||||
|
||||
continue;
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@ -424,11 +424,7 @@ const createComponents = async (uid, data) => {
|
||||
componentBody[attributeName] = await Promise.all(
|
||||
dynamiczoneValues.map(async value => {
|
||||
const { id } = await createComponent(value.__component, value);
|
||||
|
||||
return {
|
||||
__type: value.__component,
|
||||
id,
|
||||
};
|
||||
return { id, __type: value.__component };
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user