mirror of
https://github.com/strapi/strapi.git
synced 2025-09-25 16:29:34 +00:00
restructure updateRelations - connect
This commit is contained in:
parent
3ffc748b86
commit
eb8d79e0c8
@ -505,10 +505,6 @@ const createEntityManager = (db) => {
|
|||||||
const { joinTable } = attribute;
|
const { joinTable } = attribute;
|
||||||
const { joinColumn, inverseJoinColumn, orderColumnName, inverseOrderColumnName } =
|
const { joinColumn, inverseJoinColumn, orderColumnName, inverseOrderColumnName } =
|
||||||
joinTable;
|
joinTable;
|
||||||
const select = [joinColumn.name];
|
|
||||||
if (isAnyToMany(attribute)) {
|
|
||||||
select.push(orderColumnName);
|
|
||||||
}
|
|
||||||
|
|
||||||
const relsToAdd = cleanRelationData.set || cleanRelationData.connect;
|
const relsToAdd = cleanRelationData.set || cleanRelationData.connect;
|
||||||
const relIdsToadd = toIds(relsToAdd);
|
const relIdsToadd = toIds(relsToAdd);
|
||||||
@ -740,25 +736,39 @@ const createEntityManager = (db) => {
|
|||||||
differenceWith(isEqual, cleanRelationData.disconnect, cleanRelationData.connect)
|
differenceWith(isEqual, cleanRelationData.disconnect, cleanRelationData.connect)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (isEmpty(cleanRelationData.connect)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
await deleteRelations({ id, attribute, joinTable, db }, { relIdsToDelete });
|
await deleteRelations({ id, attribute, joinTable, db }, { relIdsToDelete });
|
||||||
|
|
||||||
// add/move
|
// Fetch current relations to handle ordering
|
||||||
let max;
|
let currentMovingRels;
|
||||||
const currentMovingRels = await this.createQueryBuilder(joinTable.name)
|
if (
|
||||||
.select(select)
|
isAnyToMany(attribute) ||
|
||||||
.where({
|
(isBidirectional(attribute) && isManyToAny(attribute))
|
||||||
[joinColumn.name]: id,
|
) {
|
||||||
[inverseJoinColumn.name]: { $in: relIdsToaddOrMove },
|
currentMovingRels = await this.createQueryBuilder(joinTable.name)
|
||||||
})
|
.select(select)
|
||||||
.where(joinTable.on || {})
|
.where({
|
||||||
.execute();
|
[joinColumn.name]: id,
|
||||||
const currentMovingRelsMap = currentMovingRels.reduce(
|
[inverseJoinColumn.name]: { $in: relIdsToaddOrMove },
|
||||||
(acc, rel) => Object.assign(acc, { [rel[inverseJoinColumn.name]]: rel }),
|
})
|
||||||
{}
|
.where(joinTable.on || {})
|
||||||
);
|
.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare relations to insert
|
||||||
|
const insert = cleanRelationData.connect.map((relToAdd) => ({
|
||||||
|
[joinColumn.name]: id,
|
||||||
|
[inverseJoinColumn.name]: relToAdd.id,
|
||||||
|
...(joinTable.on || {}),
|
||||||
|
...(relToAdd.__pivot || {}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
// add order value
|
||||||
if (isAnyToMany(attribute)) {
|
if (isAnyToMany(attribute)) {
|
||||||
max = (
|
const orderMax = (
|
||||||
await this.createQueryBuilder(joinTable.name)
|
await this.createQueryBuilder(joinTable.name)
|
||||||
.max(orderColumnName)
|
.max(orderColumnName)
|
||||||
.where({ [joinColumn.name]: id })
|
.where({ [joinColumn.name]: id })
|
||||||
@ -766,32 +776,60 @@ const createEntityManager = (db) => {
|
|||||||
.first()
|
.first()
|
||||||
.execute()
|
.execute()
|
||||||
).max;
|
).max;
|
||||||
|
|
||||||
|
insert.forEach((row, idx) => {
|
||||||
|
row[orderColumnName] = orderMax + idx + 1;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const nonExistingRelsIds = difference(
|
// add inv order value
|
||||||
relIdsToaddOrMove,
|
if (isBidirectional(attribute) && isManyToAny(attribute)) {
|
||||||
map(inverseJoinColumn.name, currentMovingRels)
|
const nonExistingRelsIds = difference(
|
||||||
);
|
relIdsToaddOrMove,
|
||||||
|
map(inverseJoinColumn.name, currentMovingRels)
|
||||||
|
);
|
||||||
|
|
||||||
const maxResults = await db
|
const maxResults = await db
|
||||||
.getConnection()
|
.getConnection()
|
||||||
.select(inverseJoinColumn.name)
|
.select(inverseJoinColumn.name)
|
||||||
.max(inverseOrderColumnName, { as: 'max' })
|
.max(inverseOrderColumnName, { as: 'max' })
|
||||||
.whereIn(inverseJoinColumn.name, nonExistingRelsIds)
|
.whereIn(inverseJoinColumn.name, nonExistingRelsIds)
|
||||||
.where(joinTable.on || {})
|
.where(joinTable.on || {})
|
||||||
.groupBy(inverseJoinColumn.name)
|
.groupBy(inverseJoinColumn.name)
|
||||||
.from(joinTable.name);
|
.from(joinTable.name);
|
||||||
|
|
||||||
const maxMap = maxResults.reduce(
|
const maxMap = maxResults.reduce(
|
||||||
(acc, res) => Object.assign(acc, { [res[inverseJoinColumn.name]]: res.max }),
|
(acc, res) => Object.assign(acc, { [res[inverseJoinColumn.name]]: res.max }),
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const relToAddOrMove of cleanRelationData.connect) {
|
insert.forEach((row) => {
|
||||||
const currentRel = currentMovingRelsMap[relToAddOrMove.id];
|
row[inverseOrderColumnName] = (maxMap[row[inverseJoinColumn.name]] || 0) + 1;
|
||||||
if (currentRel && isAnyToMany(attribute)) {
|
});
|
||||||
const currentOrderIsNull = currentRel[orderColumnName] === null;
|
}
|
||||||
if (!currentOrderIsNull) {
|
|
||||||
|
// insert rows
|
||||||
|
const query = this.createQueryBuilder(joinTable.name)
|
||||||
|
.insert(insert)
|
||||||
|
.onConflict([
|
||||||
|
joinColumn.name,
|
||||||
|
inverseJoinColumn.name,
|
||||||
|
...Object.keys(cleanRelationData.connect[0].__pivot || {}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (isAnyToMany(attribute)) {
|
||||||
|
query.merge([orderColumnName]);
|
||||||
|
} else {
|
||||||
|
query.ignore();
|
||||||
|
}
|
||||||
|
|
||||||
|
await query.execute();
|
||||||
|
|
||||||
|
// remove gap between orders
|
||||||
|
if (isAnyToMany(attribute)) {
|
||||||
|
currentMovingRels.sort((a, b) => b[orderColumnName] - a[orderColumnName]);
|
||||||
|
for (const currentRel of currentMovingRels) {
|
||||||
|
if (currentRel[orderColumnName] !== null) {
|
||||||
await this.createQueryBuilder(joinTable.name)
|
await this.createQueryBuilder(joinTable.name)
|
||||||
.decrement(orderColumnName, 1)
|
.decrement(orderColumnName, 1)
|
||||||
.where({
|
.where({
|
||||||
@ -800,46 +838,7 @@ const createEntityManager = (db) => {
|
|||||||
})
|
})
|
||||||
.where(joinTable.on || {})
|
.where(joinTable.on || {})
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
currentMovingRels.forEach((rel) => {
|
|
||||||
if (rel[orderColumnName] > currentRel[orderColumnName]) {
|
|
||||||
rel[orderColumnName] -= 1;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentOrderIsNull) {
|
|
||||||
max += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.createQueryBuilder(joinTable.name)
|
|
||||||
.update({
|
|
||||||
[orderColumnName]: max,
|
|
||||||
})
|
|
||||||
.where({
|
|
||||||
[joinColumn.name]: id,
|
|
||||||
[inverseJoinColumn.name]: relToAddOrMove.id,
|
|
||||||
})
|
|
||||||
.where(joinTable.on || {})
|
|
||||||
.execute();
|
|
||||||
} else if (!currentRel) {
|
|
||||||
const insert = {
|
|
||||||
[joinColumn.name]: id,
|
|
||||||
[inverseJoinColumn.name]: relToAddOrMove.id,
|
|
||||||
...(relToAddOrMove.__pivot || {}),
|
|
||||||
...(joinTable.on || {}),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isAnyToMany(attribute)) {
|
|
||||||
insert[orderColumnName] = max + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isBidirectional(attribute) && isManyToAny(attribute)) {
|
|
||||||
insert[inverseOrderColumnName] = (maxMap[relToAddOrMove.id] || 0) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.createQueryBuilder(joinTable.name).insert(insert).execute();
|
|
||||||
max += 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -909,7 +908,7 @@ const createEntityManager = (db) => {
|
|||||||
.onConflict([
|
.onConflict([
|
||||||
joinColumn.name,
|
joinColumn.name,
|
||||||
inverseJoinColumn.name,
|
inverseJoinColumn.name,
|
||||||
...Object.keys(joinTable.on || {}),
|
...Object.keys(cleanRelationData.set[0].__pivot || {}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (isAnyToMany(attribute)) {
|
if (isAnyToMany(attribute)) {
|
||||||
|
@ -99,7 +99,6 @@ describe('i18n - Find existing relations', () => {
|
|||||||
rq = await createAuthRequest({ strapi });
|
rq = await createAuthRequest({ strapi });
|
||||||
|
|
||||||
data.shops = await builder.sanitizedFixturesFor(shopModel.singularName, strapi);
|
data.shops = await builder.sanitizedFixturesFor(shopModel.singularName, strapi);
|
||||||
console.log('data.shops', data.shops);
|
|
||||||
data.products = await builder.sanitizedFixturesFor(productModel.singularName, strapi);
|
data.products = await builder.sanitizedFixturesFor(productModel.singularName, strapi);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user