mirror of
https://github.com/nocobase/nocobase
synced 2024-11-15 07:25:15 +00:00
fix: update belongs to many association that target key is not primary key (#4146)
This commit is contained in:
parent
5c7004ff43
commit
b65ee6a602
@ -0,0 +1,95 @@
|
||||
import { Database, mockDatabase } from '@nocobase/database';
|
||||
|
||||
describe('association target key', async () => {
|
||||
let db: Database;
|
||||
|
||||
beforeEach(async () => {
|
||||
db = mockDatabase();
|
||||
|
||||
await db.clean({ drop: true });
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await db.close();
|
||||
});
|
||||
|
||||
describe('belongs to many', async () => {
|
||||
let Post;
|
||||
let Tag;
|
||||
beforeEach(async () => {
|
||||
Post = db.collection({
|
||||
name: 'posts',
|
||||
fields: [
|
||||
{ type: 'string', name: 'title' },
|
||||
{ type: 'string', name: 'content' },
|
||||
{
|
||||
type: 'belongsToMany',
|
||||
name: 'tags',
|
||||
target: 'tags',
|
||||
through: 'posts_tags',
|
||||
sourceKey: 'id',
|
||||
foreignKey: 'post_id',
|
||||
otherKey: 'tag_name',
|
||||
targetKey: 'name',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
Tag = db.collection({
|
||||
name: 'tags',
|
||||
fields: [{ type: 'string', name: 'name', unique: true }],
|
||||
});
|
||||
|
||||
await db.sync({
|
||||
force: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('should set with association', async () => {
|
||||
await Post.repository.create({
|
||||
values: {
|
||||
title: 'post1',
|
||||
tags: [{ name: 'tag1' }, { name: 'tag2' }],
|
||||
},
|
||||
});
|
||||
|
||||
const post1 = await Post.repository.findOne({
|
||||
filter: {
|
||||
title: 'post1',
|
||||
},
|
||||
appends: ['tags'],
|
||||
});
|
||||
|
||||
expect(post1.tags.length).toBe(2);
|
||||
});
|
||||
|
||||
it('should create with association', async () => {
|
||||
await Tag.repository.create({
|
||||
values: [
|
||||
{
|
||||
name: 'tag1',
|
||||
},
|
||||
{
|
||||
name: 'tag2',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await Post.repository.create({
|
||||
values: {
|
||||
title: 'post1',
|
||||
tags: [{ name: 'tag1' }, { name: 'tag2' }],
|
||||
},
|
||||
});
|
||||
|
||||
const post1 = await Post.repository.findOne({
|
||||
filter: {
|
||||
title: 'post1',
|
||||
},
|
||||
appends: ['tags'],
|
||||
});
|
||||
|
||||
expect(post1.tags.length).toBe(2);
|
||||
});
|
||||
});
|
||||
});
|
@ -9,6 +9,7 @@ describe('update-guard', () => {
|
||||
let User: Collection;
|
||||
let Post: Collection;
|
||||
let Comment: Collection;
|
||||
let Tag: Collection;
|
||||
|
||||
beforeEach(async () => {
|
||||
db = mockDatabase();
|
||||
@ -20,6 +21,16 @@ describe('update-guard', () => {
|
||||
{ type: 'string', name: 'name' },
|
||||
{ type: 'integer', name: 'age' },
|
||||
{ type: 'hasMany', name: 'posts' },
|
||||
{
|
||||
type: 'belongsToMany',
|
||||
name: 'tags',
|
||||
target: 'tags',
|
||||
through: 'users_tags',
|
||||
sourceKey: 'id',
|
||||
foreignKey: 'userId',
|
||||
otherKey: 'tagName',
|
||||
targetKey: 'name',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
@ -48,6 +59,11 @@ describe('update-guard', () => {
|
||||
],
|
||||
});
|
||||
|
||||
Tag = db.collection({
|
||||
name: 'tags',
|
||||
fields: [{ type: 'string', name: 'name', unique: true }],
|
||||
});
|
||||
|
||||
await db.sync({
|
||||
force: true,
|
||||
alter: { drop: false },
|
||||
@ -55,22 +71,49 @@ describe('update-guard', () => {
|
||||
|
||||
const repository = User.repository;
|
||||
|
||||
await repository.createMany({
|
||||
records: [
|
||||
await repository.create({
|
||||
values: [
|
||||
{
|
||||
name: 'u1',
|
||||
age: 10,
|
||||
posts: [{ title: 'u1t1', comments: [{ content: 'u1t1c1' }] }],
|
||||
tags: [
|
||||
{
|
||||
name: 't1',
|
||||
},
|
||||
{
|
||||
name: 't2',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'u2',
|
||||
age: 20,
|
||||
posts: [{ title: 'u2t1', comments: [{ content: 'u2t1c1' }] }],
|
||||
tags: [
|
||||
{
|
||||
name: 't1',
|
||||
},
|
||||
{
|
||||
name: 't2',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'u3',
|
||||
age: 30,
|
||||
posts: [{ title: 'u3t1', comments: [{ content: 'u3t1c1' }] }],
|
||||
tags: [
|
||||
{
|
||||
name: 't1',
|
||||
},
|
||||
{
|
||||
name: 't2',
|
||||
},
|
||||
{
|
||||
name: 't3',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
@ -80,6 +123,26 @@ describe('update-guard', () => {
|
||||
await db.close();
|
||||
});
|
||||
|
||||
test('association values', async () => {
|
||||
const values = {
|
||||
name: 'u1',
|
||||
tags: [
|
||||
{
|
||||
name: 't1',
|
||||
},
|
||||
{
|
||||
name: 't2',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const guard = new UpdateGuard();
|
||||
guard.setModel(User.model);
|
||||
|
||||
const sanitized = guard.sanitize(values);
|
||||
console.log(sanitized);
|
||||
});
|
||||
|
||||
test('white list', () => {
|
||||
const values = {
|
||||
name: '123',
|
||||
|
@ -442,7 +442,11 @@ export async function updateMultipleAssociation(
|
||||
const targetKey = (association as any).targetKey || 'id';
|
||||
|
||||
if (item[targetKey]) {
|
||||
setItems.push(item[targetKey]);
|
||||
const attributes = {
|
||||
[targetKey]: item[targetKey],
|
||||
};
|
||||
const instance = association.target.build(attributes, { isNewRecord: false });
|
||||
setItems.push(instance);
|
||||
}
|
||||
|
||||
objectItems.push(item);
|
||||
@ -511,7 +515,7 @@ export async function updateMultipleAssociation(
|
||||
}
|
||||
const addAccessor = association.accessors.add;
|
||||
|
||||
await model[addAccessor](instance[association.target.primaryKeyAttribute], accessorOptions);
|
||||
await model[addAccessor](instance, accessorOptions);
|
||||
|
||||
if (!recursive) {
|
||||
continue;
|
||||
|
@ -148,10 +148,9 @@ export class UpdateGuard {
|
||||
return value;
|
||||
}
|
||||
|
||||
const associationKeyName =
|
||||
associationObj.associationType == 'BelongsTo' || associationObj.associationType == 'HasOne'
|
||||
? (<any>associationObj).targetKey
|
||||
: associationObj.target.primaryKeyAttribute;
|
||||
const associationKeyName = (<any>associationObj).targetKey
|
||||
? (<any>associationObj).targetKey
|
||||
: associationObj.target.primaryKeyAttribute;
|
||||
|
||||
if (value[associationKeyName]) {
|
||||
return lodash.pick(value, [associationKeyName, ...Object.keys(associationObj.target.associations)]);
|
||||
|
Loading…
Reference in New Issue
Block a user