feat: destroy association field after target collection destroy (#376)

This commit is contained in:
ChengLei Shao 2022-05-22 08:50:58 +08:00 committed by GitHub
parent 16f861ad7d
commit c6839b30c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 74 additions and 1 deletions

View File

@ -0,0 +1,50 @@
import Database, { Collection as DBCollection } from '@nocobase/database';
import Application from '@nocobase/server';
import { createApp } from '.';
describe('collections repository', () => {
let db: Database;
let app: Application;
let Collection: DBCollection;
let Field: DBCollection;
beforeEach(async () => {
app = await createApp();
await app.db.sync();
db = app.db;
Collection = db.getCollection('collections');
Field = db.getCollection('fields');
});
afterEach(async () => {
await app.destroy();
});
it('should remove association field after collection destroy', async () => {
await Collection.repository.create({
context: {},
values: {
name: 'posts',
fields: [{ type: 'hasMany', name: 'comments', options: { target: 'comments' } }],
},
});
await Collection.repository.create({
context: {},
values: {
name: 'comments',
fields: [{ type: 'string', name: 'content' }],
},
});
await db.getRepository('collections').destroy({
filter: {
name: 'comments',
},
});
const fields = await db.getRepository('fields').find();
expect(fields.length).toEqual(0);
});
});

View File

@ -41,6 +41,7 @@ export default {
target: 'collections',
foreignKey: 'collectionName',
targetKey: 'name',
onDelete: 'CASCADE',
},
{
type: 'hasMany',
@ -60,7 +61,7 @@ export default {
type: 'belongsTo',
name: 'uiSchema',
target: 'uiSchemas',
foreignKey: 'uiSchemaUid'
foreignKey: 'uiSchemaUid',
},
{
type: 'json',

View File

@ -58,6 +58,28 @@ export class CollectionManagerPlugin extends Plugin {
}
});
this.app.db.on('collections.afterDestroy', async (model, { transaction }) => {
const name = model.get('name');
const fields = await this.app.db.getRepository('fields').find({
filter: {
'type.$in': ['belongsToMany', 'belongsTo', 'hasMany', 'hasOne'],
},
transaction,
});
const deleteFieldsKey = fields
.filter((field) => (field.get('options') as any)?.target === name)
.map((field) => field.get('key') as string);
await this.app.db.getRepository('fields').destroy({
filter: {
'key.$in': deleteFieldsKey,
},
transaction,
});
});
this.app.db.on('fields.afterCreate', async (model, { context, transaction }) => {
if (context) {
await model.migrate({ transaction });