Fix relation not correctly set when uploadinga new file to an entity

This commit is contained in:
Pierre Noël 2022-08-23 10:56:36 +02:00
parent e8cdc26240
commit f681c064c4
2 changed files with 81 additions and 1 deletions

View File

@ -402,6 +402,21 @@ const createEntityManager = (db) => {
continue;
}
// delete previous relations
const where = { $or: [] };
for (const { field, related_type: relatedType, related_id: relatedId } of rows) {
const isMorphOne =
db.metadata.get(relatedType).attributes[field].relation === 'morphOne';
if (isMorphOne) {
where.$or.push({ related_type: relatedType, field, related_id: relatedId });
}
}
if (!_.isEmpty(where.$or)) {
await this.createQueryBuilder(joinTable.name).delete().where(where).execute();
}
await this.createQueryBuilder(joinTable.name).insert(rows).execute();
continue;
@ -503,6 +518,8 @@ const createEntityManager = (db) => {
// set columns
const { idColumn, typeColumn } = targetAttribute.morphColumn;
// update instead of deleting because the relation is directly on the entity table
// and not in a join table
await this.createQueryBuilder(target)
.update({ [idColumn.name]: null, [typeColumn.name]: null })
.where({ [idColumn.name]: id, [typeColumn.name]: uid })
@ -581,6 +598,21 @@ const createEntityManager = (db) => {
continue;
}
// delete previous relations
const where = { $or: [] };
for (const { field, related_type: relatedType, related_id: relatedId } of rows) {
const isMorphOne =
db.metadata.get(relatedType).attributes[field].relation === 'morphOne';
if (isMorphOne) {
where.$or.push({ related_type: relatedType, field, related_id: relatedId });
}
}
if (!_.isEmpty(where.$or)) {
await this.createQueryBuilder(joinTable.name).delete().where(where).execute();
}
await this.createQueryBuilder(joinTable.name).insert(rows).execute();
continue;

View File

@ -9,6 +9,7 @@ const { createStrapiInstance } = require('../../../../../test/helpers/strapi');
const { createContentAPIRequest } = require('../../../../../test/helpers/request');
const builder = createTestBuilder();
const data = { dogs: [] };
let strapi;
let rq;
@ -24,7 +25,7 @@ const dogModel = {
},
};
describe('Upload plugin end to end tests', () => {
describe('Upload plugin', () => {
beforeAll(async () => {
await builder.addContentType(dogModel).build();
strapi = await createStrapiInstance();
@ -155,6 +156,8 @@ describe('Upload plugin end to end tests', () => {
id: expect.anything(),
},
});
data.dogs.push(res.body);
});
test('With a pdf', async () => {
@ -183,6 +186,51 @@ describe('Upload plugin end to end tests', () => {
id: expect.anything(),
},
});
data.dogs.push(res.body);
});
});
// see https://github.com/strapi/strapi/issues/14125
describe('File relations are correctly removed', () => {
test('Update an entity with a file correctly removes the relation between the entity and its old file', async () => {
const res = await rq({
method: 'PUT',
url: `/dogs/${data.dogs[0].data.id}?populate=*`,
formData: {
data: '{}',
'files.profilePicture': fs.createReadStream(path.join(__dirname, '../utils/strapi.jpg')),
},
});
expect(res.statusCode).toBe(200);
expect(res.body.data.attributes.profilePicture.data.id).not.toBe(
data.dogs[0].data.attributes.profilePicture.data.id
);
data.dogs[0] = res.body;
});
test('Update a file with an entity correctly removes the relation between the entity and its old file', async () => {
const fileId = data.dogs[1].data.attributes.profilePicture.data.id;
await strapi.entityService.update('plugin::upload.file', fileId, {
data: {
related: [
{
id: data.dogs[0].data.id,
__type: 'api::dog.dog',
__pivot: { field: 'profilePicture' },
},
],
},
});
const res = await rq({
method: 'GET',
url: `/dogs/${data.dogs[0].data.id}?populate=*`,
});
expect(res.body.data.attributes.profilePicture.data.id).toBe(fileId);
data.dogs[0] = res.body;
});
});
});