fix: target key value is empty (#4796)

This commit is contained in:
chenos 2024-07-05 06:47:21 +08:00 committed by GitHub
parent 7084e8d35f
commit 5dc626d2d6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 238 additions and 2 deletions

View File

@ -0,0 +1,232 @@
/**
* This file is part of the NocoBase (R) project.
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
* Authors: NocoBase Team.
*
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import { Database } from '../database';
import { mockDatabase } from './index';
describe('targetKey', () => {
let db: Database;
beforeEach(async () => {
db = mockDatabase();
await db.clean({ drop: true });
});
afterEach(async () => {
await db.close();
});
test('default targetKey', async () => {
db.collection({
name: 'a1',
fields: [
{
type: 'hasMany',
name: 'b1',
target: 'b1',
},
],
});
db.collection({
name: 'b1',
fields: [],
});
await db.sync();
const r1 = db.getRepository('a1');
const r2 = db.getRepository('b1');
const b1 = await r2.create({
values: {},
});
await r1.create({
values: {
name: 'a1',
b1: [b1.toJSON()],
},
});
const b1r = await b1.reload();
expect(b1r.a1Id).toBe(b1.id);
});
test('targetKey=code', async () => {
db.collection({
name: 'a1',
fields: [
{
type: 'hasMany',
name: 'b1',
target: 'b1',
targetKey: 'code',
},
],
});
db.collection({
name: 'b1',
fields: [
{
type: 'string',
name: 'code',
},
],
});
await db.sync();
const r1 = db.getRepository('a1');
const r2 = db.getRepository('b1');
const b1 = await r2.create({
values: {},
});
await r1.create({
values: {
name: 'a1',
b1: [b1.toJSON()],
},
});
const b1r = await b1.reload();
expect(b1r.a1Id).toBe(b1.id);
});
test('should throw an error', async () => {
db.collection({
name: 'a1',
fields: [
{
type: 'hasMany',
name: 'b1',
target: 'b1',
targetKey: 'code',
},
],
});
db.collection({
name: 'b1',
fields: [
{
type: 'string',
name: 'code',
unique: true,
},
],
});
await db.sync();
const r1 = db.getRepository('a1');
const r2 = db.getRepository('b1');
const b1 = await r2.create({
values: {},
});
await expect(async () => {
await r1.create({
values: {
name: 'a1',
b1: [b1.toJSON()],
},
});
}).rejects.toThrowError('code field value is empty');
});
test('should find by code', async () => {
db.collection({
name: 'a1',
fields: [
{
type: 'hasMany',
name: 'b1',
target: 'b1',
targetKey: 'code',
},
],
});
db.collection({
name: 'b1',
fields: [
{
type: 'string',
name: 'code',
unique: true,
},
],
});
await db.sync();
const r1 = db.getRepository('a1');
const r2 = db.getRepository('b1');
const b1 = await r2.create({
values: {
code: 'code1',
},
});
await r1.create({
values: {
name: 'a1',
b1: [b1.toJSON()],
},
});
const b1r = await b1.reload();
expect(b1r.a1Id).toBe(b1.id);
});
test('should find by a1Code and code', async () => {
db.collection({
name: 'a1',
fields: [
{
type: 'string',
name: 'code',
unique: true,
},
{
type: 'hasMany',
name: 'b1',
target: 'b1',
sourceKey: 'code',
foreignKey: 'a1Code',
targetKey: 'code',
},
],
});
db.collection({
name: 'b1',
indexes: [
{
type: 'UNIQUE',
fields: ['a1Code', 'code'],
},
],
fields: [
{
type: 'string',
name: 'a1Code',
},
{
type: 'string',
name: 'code',
},
],
});
await db.sync();
const r1 = db.getRepository('a1');
const r2 = db.getRepository('b1');
await r2.create({
values: {
code: 'b1',
},
});
const b1 = await r2.create({
values: {
code: 'b1',
},
});
await r1.create({
values: {
code: 'a1',
b1: [b1.toJSON()],
},
});
const b1r = await b1.reload();
expect(b1r.a1Code).toBe('a1');
expect(b1r.code).toBe('b1');
});
});

View File

@ -490,6 +490,10 @@ export async function updateMultipleAssociation(
accessorOptions['through'] = throughValue;
}
if (pk !== targetKey && !isUndefinedOrNull(item[pk]) && isUndefinedOrNull(item[targetKey])) {
throw new Error(`${targetKey} field value is empty`);
}
if (isUndefinedOrNull(item[targetKey])) {
// create new record
const instance = await model[createAccessor](item, accessorOptions);

View File

@ -157,8 +157,8 @@ export class UpdateGuard {
return value;
}
const associationKeyName = (<any>associationObj).targetKey
? (<any>associationObj).targetKey
const associationKeyName = associationObj?.['options']?.targetKey
? associationObj['options'].targetKey
: associationObj.target.primaryKeyAttribute;
if (value[associationKeyName]) {