mirror of
https://github.com/nocobase/nocobase
synced 2024-11-15 10:06:22 +00:00
fix: update assocations in belongs to many repository (#3229)
This commit is contained in:
parent
c129889df6
commit
f60c7626e0
@ -344,6 +344,38 @@ describe('belongs to many', () => {
|
||||
await db.close();
|
||||
});
|
||||
|
||||
it('should create associations with associations', async () => {
|
||||
const p1 = await Post.repository.create({
|
||||
values: {
|
||||
title: 'p1',
|
||||
},
|
||||
});
|
||||
|
||||
const postTagsRepository = new BelongsToManyRepository(Post, 'tags', p1.id);
|
||||
|
||||
await postTagsRepository.create({
|
||||
values: {
|
||||
name: 't1',
|
||||
colors: [
|
||||
{
|
||||
name: 'red',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const t1 = await postTagsRepository.findOne({
|
||||
filter: {
|
||||
name: 't1',
|
||||
},
|
||||
appends: ['colors'],
|
||||
});
|
||||
|
||||
expect(t1.name).toEqual('t1');
|
||||
expect(t1.colors.length).toEqual(1);
|
||||
expect(t1.colors[0].name).toEqual('red');
|
||||
});
|
||||
|
||||
test('create with through values', async () => {
|
||||
const p1 = await Post.repository.create({
|
||||
values: {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import lodash from 'lodash';
|
||||
import { BelongsToMany, Op, Transaction } from 'sequelize';
|
||||
import { AggregateOptions, CreateOptions, DestroyOptions, TargetKey } from '../repository';
|
||||
import { updateThroughTableValue } from '../update-associations';
|
||||
import { updateAssociations, updateThroughTableValue } from '../update-associations';
|
||||
import { MultipleRelationRepository } from './multiple-relation-repository';
|
||||
import { transaction } from './relation-repository';
|
||||
import { AssociatedOptions, PrimaryKeyWithThroughValues } from './types';
|
||||
@ -53,7 +53,9 @@ export class BelongsToManyRepository extends MultipleRelationRepository {
|
||||
transaction,
|
||||
};
|
||||
|
||||
return sourceModel[createAccessor](values, createOptions);
|
||||
const instance = await sourceModel[createAccessor](values, createOptions);
|
||||
await updateAssociations(instance, values, { ...options, transaction });
|
||||
return instance;
|
||||
}
|
||||
|
||||
@transaction((args, transaction) => {
|
||||
@ -129,49 +131,6 @@ export class BelongsToManyRepository extends MultipleRelationRepository {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected async setTargets(
|
||||
call: 'add' | 'set',
|
||||
options: TargetKey | TargetKey[] | PrimaryKeyWithThroughValues | PrimaryKeyWithThroughValues[] | AssociatedOptions,
|
||||
) {
|
||||
const handleKeys: TargetKey[] | PrimaryKeyWithThroughValues[] = this.convertTks(options) as any;
|
||||
|
||||
const transaction = await this.getTransaction(options, false);
|
||||
|
||||
const sourceModel = await this.getSourceModel(transaction);
|
||||
|
||||
const setObj = (<any>handleKeys).reduce((carry, item) => {
|
||||
if (Array.isArray(item)) {
|
||||
carry[item[0]] = item[1];
|
||||
} else {
|
||||
carry[item] = true;
|
||||
}
|
||||
return carry;
|
||||
}, {});
|
||||
|
||||
const targetKeys = Object.keys(setObj);
|
||||
const association = this.association;
|
||||
|
||||
const targetObjects = await this.targetModel.findAll({
|
||||
where: {
|
||||
[association['targetKey']]: targetKeys,
|
||||
},
|
||||
transaction,
|
||||
});
|
||||
|
||||
await sourceModel[this.accessors()[call]](targetObjects, {
|
||||
transaction,
|
||||
});
|
||||
|
||||
for (const [id, throughValues] of Object.entries(setObj)) {
|
||||
if (typeof throughValues === 'object') {
|
||||
const instance = await this.targetModel.findByPk(id, {
|
||||
transaction,
|
||||
});
|
||||
await updateThroughTableValue(instance, this.throughName(), throughValues, sourceModel, transaction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@transaction((args, transaction) => {
|
||||
return {
|
||||
tk: args[0],
|
||||
@ -244,4 +203,47 @@ export class BelongsToManyRepository extends MultipleRelationRepository {
|
||||
throughModel() {
|
||||
return (<any>this.association).through.model;
|
||||
}
|
||||
|
||||
protected async setTargets(
|
||||
call: 'add' | 'set',
|
||||
options: TargetKey | TargetKey[] | PrimaryKeyWithThroughValues | PrimaryKeyWithThroughValues[] | AssociatedOptions,
|
||||
) {
|
||||
const handleKeys: TargetKey[] | PrimaryKeyWithThroughValues[] = this.convertTks(options) as any;
|
||||
|
||||
const transaction = await this.getTransaction(options, false);
|
||||
|
||||
const sourceModel = await this.getSourceModel(transaction);
|
||||
|
||||
const setObj = (<any>handleKeys).reduce((carry, item) => {
|
||||
if (Array.isArray(item)) {
|
||||
carry[item[0]] = item[1];
|
||||
} else {
|
||||
carry[item] = true;
|
||||
}
|
||||
return carry;
|
||||
}, {});
|
||||
|
||||
const targetKeys = Object.keys(setObj);
|
||||
const association = this.association;
|
||||
|
||||
const targetObjects = await this.targetModel.findAll({
|
||||
where: {
|
||||
[association['targetKey']]: targetKeys,
|
||||
},
|
||||
transaction,
|
||||
});
|
||||
|
||||
await sourceModel[this.accessors()[call]](targetObjects, {
|
||||
transaction,
|
||||
});
|
||||
|
||||
for (const [id, throughValues] of Object.entries(setObj)) {
|
||||
if (typeof throughValues === 'object') {
|
||||
const instance = await this.targetModel.findByPk(id, {
|
||||
transaction,
|
||||
});
|
||||
await updateThroughTableValue(instance, this.throughName(), throughValues, sourceModel, transaction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,58 @@ describe('destroy action with acl', () => {
|
||||
await app.destroy();
|
||||
});
|
||||
|
||||
it('should create role through user resource', async () => {
|
||||
const UserCollection = app.db.getCollection('users');
|
||||
|
||||
const user = await UserCollection.repository.create({
|
||||
values: {
|
||||
name: 'test_user',
|
||||
},
|
||||
});
|
||||
|
||||
const userRolesRepository = app.db.getRepository('users.roles', user.get('id'));
|
||||
const roleName = 'r_voluptas-assumenda-omnis';
|
||||
await userRolesRepository.create({
|
||||
values: {
|
||||
name: roleName,
|
||||
snippets: ['!ui.*', '!pm', '!pm.*'],
|
||||
title: 'r_harum-qui-doloremque',
|
||||
resources: [
|
||||
{
|
||||
usingActionsConfig: true,
|
||||
actions: [
|
||||
{
|
||||
name: 'create',
|
||||
fields: ['id', 'nickname', 'username', 'email', 'phone', 'password', 'roles'],
|
||||
scope: null,
|
||||
},
|
||||
{
|
||||
name: 'view',
|
||||
fields: ['id', 'nickname', 'username', 'email', 'phone', 'password', 'roles'],
|
||||
scope: {
|
||||
name: '数据范围',
|
||||
scope: {
|
||||
createdById: '{{ ctx.state.currentUser.id }}',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
name: 'users',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const role = await app.db.getRepository('roles').findOne({
|
||||
filter: {
|
||||
name: roleName,
|
||||
},
|
||||
appends: ['resources'],
|
||||
});
|
||||
|
||||
expect(role.get('resources').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should load the association collection when the source collection does not have the createdById field', async () => {
|
||||
const A = app.collection({
|
||||
name: 'a',
|
||||
|
Loading…
Reference in New Issue
Block a user