Fix/save through table data (#1714)
* fix: save through table data * chore: variable name * fix: format
This commit is contained in:
parent
1654b42037
commit
9fc8f5389b
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user