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();
|
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 () => {
|
test('create with through values', async () => {
|
||||||
const p1 = await Post.repository.create({
|
const p1 = await Post.repository.create({
|
||||||
values: {
|
values: {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import lodash from 'lodash';
|
import lodash from 'lodash';
|
||||||
import { BelongsToMany, Op, Transaction } from 'sequelize';
|
import { BelongsToMany, Op, Transaction } from 'sequelize';
|
||||||
import { AggregateOptions, CreateOptions, DestroyOptions, TargetKey } from '../repository';
|
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 { MultipleRelationRepository } from './multiple-relation-repository';
|
||||||
import { transaction } from './relation-repository';
|
import { transaction } from './relation-repository';
|
||||||
import { AssociatedOptions, PrimaryKeyWithThroughValues } from './types';
|
import { AssociatedOptions, PrimaryKeyWithThroughValues } from './types';
|
||||||
@ -53,7 +53,9 @@ export class BelongsToManyRepository extends MultipleRelationRepository {
|
|||||||
transaction,
|
transaction,
|
||||||
};
|
};
|
||||||
|
|
||||||
return sourceModel[createAccessor](values, createOptions);
|
const instance = await sourceModel[createAccessor](values, createOptions);
|
||||||
|
await updateAssociations(instance, values, { ...options, transaction });
|
||||||
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@transaction((args, transaction) => {
|
@transaction((args, transaction) => {
|
||||||
@ -129,49 +131,6 @@ export class BelongsToManyRepository extends MultipleRelationRepository {
|
|||||||
return true;
|
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) => {
|
@transaction((args, transaction) => {
|
||||||
return {
|
return {
|
||||||
tk: args[0],
|
tk: args[0],
|
||||||
@ -244,4 +203,47 @@ export class BelongsToManyRepository extends MultipleRelationRepository {
|
|||||||
throughModel() {
|
throughModel() {
|
||||||
return (<any>this.association).through.model;
|
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();
|
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 () => {
|
it('should load the association collection when the source collection does not have the createdById field', async () => {
|
||||||
const A = app.collection({
|
const A = app.collection({
|
||||||
name: 'a',
|
name: 'a',
|
||||||
|
Loading…
Reference in New Issue
Block a user