Fix/save through table data (#1714)

* fix: save through table data

* chore: variable name

* fix: format
This commit is contained in:
ChengLei Shao 2023-04-17 14:46:16 +08:00 committed by GitHub
parent 1654b42037
commit 9fc8f5389b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 100 additions and 22 deletions

View File

@ -181,6 +181,80 @@ describe('repository.find', () => {
});
});
describe('repository create with belongs to many', () => {
let db: Database;
beforeEach(async () => {
db = mockDatabase({
tablePrefix: '',
});
await db.clean({ drop: true });
});
afterEach(async () => [await db.close()]);
it('should save value at through table', async () => {
const Product = db.collection({
name: 'products',
fields: [
{ type: 'string', name: 'name' },
{ type: 'integer', name: 'price' },
],
});
const OrderProduct = db.collection({
name: 'orders_products',
fields: [{ type: 'integer', name: 'quantity' }],
});
const Order = db.collection({
name: 'orders',
fields: [
{
type: 'belongsToMany',
name: 'products',
through: 'orders_products',
},
],
});
await db.sync();
await Product.repository.create({
values: [
{
name: 'product1',
price: 100,
},
{
name: 'product2',
price: 200,
},
],
});
const p1 = await Product.repository.findOne({
filter: { name: 'product1' },
});
await Order.repository.create({
values: {
products: [
{
id: p1.get('id'),
orders_products: {
quantity: 20,
},
},
],
},
});
const through = await OrderProduct.repository.findOne();
expect(through.get('quantity')).toBe(20);
});
});
describe('repository.create', () => {
let db: Database;
let User: Collection;

View File

@ -6,10 +6,11 @@ import {
HasOne,
Hookable,
ModelStatic,
Transactionable
Transactionable,
} from 'sequelize';
import { Model } from './model';
import { UpdateGuard } from './update-guard';
import lodash from 'lodash';
function isUndefinedOrNull(value: any) {
return typeof value === 'undefined' || value === null;
@ -396,38 +397,40 @@ export async function updateMultipleAssociation(
return;
}
if (!Array.isArray(value)) {
value = [value];
}
value = lodash.castArray(value);
const list1 = []; // to be setted
const list2 = []; // to be added
const created = [];
const setItems = []; // to be setted
const objectItems = []; // to be added
// iterate item in value
for (const item of value) {
if (isUndefinedOrNull(item)) {
continue;
}
if (isStringOrNumber(item)) {
list1.push(item);
setItems.push(item);
} else if (item instanceof Model) {
list1.push(item);
setItems.push(item);
} else if (item.sequelize) {
list1.push(item);
setItems.push(item);
} else if (typeof item === 'object') {
const targetKey = (association as any).targetKey || 'id';
if (item[targetKey]) {
created.push(item[targetKey]);
list1.push(item[targetKey]);
setItems.push(item[targetKey]);
}
list2.push(item);
objectItems.push(item);
}
}
// associate targets in lists1
await model[setAccessor](list1, { transaction, context, individualHooks: true });
await model[setAccessor](setItems, { transaction, context, individualHooks: true });
const list3 = [];
for (const item of list2) {
const newItems = [];
for (const item of objectItems) {
const pk = association.target.primaryKeyAttribute;
const through = (<any>association).through ? (<any>association).through.model.name : null;
@ -446,13 +449,14 @@ export async function updateMultipleAssociation(
if (isUndefinedOrNull(item[pk])) {
// create new record
const instance = await model[createAccessor](item, accessorOptions);
await updateAssociations(instance, item, {
...options,
transaction,
associationContext: association,
updateAssociationValues: keys,
});
list3.push(instance);
newItems.push(instance);
} else {
// set & update record
const instance = await association.target.findByPk<any>(item[pk], {
@ -462,9 +466,9 @@ export async function updateMultipleAssociation(
continue;
}
const addAccessor = association.accessors.add;
if (!created.includes(item[pk])) {
await model[addAccessor](item[pk], accessorOptions);
}
await model[addAccessor](item[pk], accessorOptions);
if (!recursive) {
continue;
}
@ -477,11 +481,11 @@ export async function updateMultipleAssociation(
associationContext: association,
updateAssociationValues: keys,
});
list3.push(instance);
newItems.push(instance);
}
}
model.setDataValue(key, list1.concat(list3));
model.setDataValue(key, setItems.concat(newItems));
} catch (error) {
throw error;
}