mirror of
https://github.com/strapi/strapi.git
synced 2025-11-07 21:58:23 +00:00
fix: relations are not returned in the correct order
When removing or adding a relation in an entity, other entities from the same Content Type were seeing that same relation reordered. Cause: We were updating the order of the other entities when we should only be updating the inverse order.
This commit is contained in:
parent
1141d65f7d
commit
f6246c145d
@ -206,29 +206,40 @@ const cleanOrderColumns = async ({ id, attribute, db, inverseRelIds, transaction
|
|||||||
|
|
||||||
const { joinTable } = attribute;
|
const { joinTable } = attribute;
|
||||||
const { joinColumn, inverseJoinColumn, orderColumnName, inverseOrderColumnName } = joinTable;
|
const { joinColumn, inverseJoinColumn, orderColumnName, inverseOrderColumnName } = joinTable;
|
||||||
|
|
||||||
|
// Build the update query based on the relation type
|
||||||
|
// See query below for more details
|
||||||
const update = [];
|
const update = [];
|
||||||
const updateBinding = [];
|
const updateBinding = [];
|
||||||
const select = ['??'];
|
const selectEntityRelations = db.connection(joinTable.name).select('id');
|
||||||
const selectBinding = ['id'];
|
const selectInverseEntityRelations = db.connection(joinTable.name).select('id');
|
||||||
const where = [];
|
|
||||||
const whereBinding = [];
|
|
||||||
|
|
||||||
if (hasOrderColumn(attribute) && id) {
|
if (hasOrderColumn(attribute) && id) {
|
||||||
|
// Update order column of join table
|
||||||
update.push('?? = b.src_order');
|
update.push('?? = b.src_order');
|
||||||
updateBinding.push(orderColumnName);
|
updateBinding.push(orderColumnName);
|
||||||
select.push('ROW_NUMBER() OVER (PARTITION BY ?? ORDER BY ??) AS src_order');
|
|
||||||
selectBinding.push(joinColumn.name, orderColumnName);
|
// Calculate order column of entity relations
|
||||||
where.push('?? = ?');
|
selectEntityRelations
|
||||||
whereBinding.push(joinColumn.name, id);
|
.rowNumber('src_order', joinColumn.name, orderColumnName)
|
||||||
|
.where(joinColumn.name, id);
|
||||||
|
|
||||||
|
// Do not update the order column of entities that were also using the same relations
|
||||||
|
selectInverseEntityRelations.select({ src_order: orderColumnName });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasInverseOrderColumn(attribute) && !isEmpty(inverseRelIds)) {
|
if (hasInverseOrderColumn(attribute) && !isEmpty(inverseRelIds)) {
|
||||||
|
// Update inverse order column of join table
|
||||||
update.push('?? = b.inv_order');
|
update.push('?? = b.inv_order');
|
||||||
updateBinding.push(inverseOrderColumnName);
|
updateBinding.push(inverseOrderColumnName);
|
||||||
select.push('ROW_NUMBER() OVER (PARTITION BY ?? ORDER BY ??) AS inv_order');
|
|
||||||
selectBinding.push(inverseJoinColumn.name, inverseOrderColumnName);
|
// Calculate inv order column of inverse side for the entity relations
|
||||||
where.push(`?? IN (${inverseRelIds.map(() => '?').join(', ')})`);
|
selectEntityRelations.rowNumber('inv_order', inverseJoinColumn.name, inverseOrderColumnName);
|
||||||
whereBinding.push(inverseJoinColumn.name, ...inverseRelIds);
|
|
||||||
|
// Calculate inv order column of entities that were also using the same relations
|
||||||
|
selectInverseEntityRelations
|
||||||
|
.rowNumber('inv_order', inverseJoinColumn.name, inverseOrderColumnName)
|
||||||
|
.where(inverseJoinColumn.name, 'in', inverseRelIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (strapi.db.dialect.client) {
|
switch (strapi.db.dialect.client) {
|
||||||
@ -237,16 +248,20 @@ const cleanOrderColumns = async ({ id, attribute, db, inverseRelIds, transaction
|
|||||||
await db
|
await db
|
||||||
.getConnection()
|
.getConnection()
|
||||||
.raw(
|
.raw(
|
||||||
`UPDATE
|
`UPDATE ?? as a,
|
||||||
?? as a,
|
|
||||||
(
|
(
|
||||||
SELECT ${select.join(', ')}
|
${selectEntityRelations.toSQL().sql}
|
||||||
FROM ??
|
UNION
|
||||||
WHERE ${where.join(' OR ')}
|
${selectInverseEntityRelations.toSQL().sql}
|
||||||
) AS b
|
) AS b
|
||||||
SET ${update.join(', ')}
|
SET ${update.join(', ')}
|
||||||
WHERE b.id = a.id`,
|
WHERE b.id = a.id`,
|
||||||
[joinTable.name, ...selectBinding, joinTable.name, ...whereBinding, ...updateBinding]
|
[
|
||||||
|
joinTable.name,
|
||||||
|
...selectEntityRelations.toSQL().bindings,
|
||||||
|
...selectInverseEntityRelations.toSQL().bindings,
|
||||||
|
...updateBinding,
|
||||||
|
]
|
||||||
)
|
)
|
||||||
.transacting(trx);
|
.transacting(trx);
|
||||||
break;
|
break;
|
||||||
@ -254,12 +269,21 @@ const cleanOrderColumns = async ({ id, attribute, db, inverseRelIds, transaction
|
|||||||
UPDATE
|
UPDATE
|
||||||
:joinTable: as a,
|
:joinTable: as a,
|
||||||
(
|
(
|
||||||
|
-- Update the updated entity order columns
|
||||||
SELECT
|
SELECT
|
||||||
id,
|
id,
|
||||||
ROW_NUMBER() OVER ( PARTITION BY :joinColumn: ORDER BY :orderColumn:) AS src_order,
|
ROW_NUMBER() OVER ( PARTITION BY :joinColumn: ORDER BY :orderColumn:) AS src_order,
|
||||||
ROW_NUMBER() OVER ( PARTITION BY :inverseJoinColumn: ORDER BY :inverseOrderColumn:) AS inv_order
|
ROW_NUMBER() OVER ( PARTITION BY :inverseJoinColumn: ORDER BY :inverseOrderColumn:) AS inv_order
|
||||||
FROM :joinTable:
|
FROM :joinTable:
|
||||||
WHERE :joinColumn: = :id OR :inverseJoinColumn: IN (:inverseRelIds)
|
WHERE :joinColumn: = :id
|
||||||
|
UNION
|
||||||
|
-- Update the inverse side order columns of entities that relate to the same inverse side
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
:orderColumn: AS src_order,
|
||||||
|
ROW_NUMBER() OVER ( PARTITION BY :inverseJoinColumn: ORDER BY :inverseOrderColumn:) AS inv_order
|
||||||
|
FROM :joinTable:
|
||||||
|
WHERE :inverseJoinColumn: IN (:inverseRelIds)
|
||||||
) AS b
|
) AS b
|
||||||
SET :orderColumn: = b.src_order, :inverseOrderColumn: = b.inv_order
|
SET :orderColumn: = b.src_order, :inverseOrderColumn: = b.inv_order
|
||||||
WHERE b.id = a.id;
|
WHERE b.id = a.id;
|
||||||
@ -274,12 +298,17 @@ const cleanOrderColumns = async ({ id, attribute, db, inverseRelIds, transaction
|
|||||||
`UPDATE ?? as a
|
`UPDATE ?? as a
|
||||||
SET ${update.join(', ')}
|
SET ${update.join(', ')}
|
||||||
FROM (
|
FROM (
|
||||||
SELECT ${select.join(', ')}
|
${selectEntityRelations.toSQL().sql}
|
||||||
FROM ??
|
UNION
|
||||||
WHERE ${where.join(' OR ')}
|
${selectInverseEntityRelations.toSQL().sql}
|
||||||
) AS b
|
) AS b
|
||||||
WHERE b.id = a.id`,
|
WHERE b.id = a.id`,
|
||||||
[joinTableName, ...updateBinding, ...selectBinding, joinTableName, ...whereBinding]
|
[
|
||||||
|
joinTableName,
|
||||||
|
...updateBinding,
|
||||||
|
...selectEntityRelations.toSQL().bindings,
|
||||||
|
...selectInverseEntityRelations.toSQL().bindings,
|
||||||
|
]
|
||||||
)
|
)
|
||||||
.transacting(trx);
|
.transacting(trx);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user