fix: destroy through table record referencing collections table (#1611)

* test: destory through table record referencing collections table

* fix: belongs to many fields to reference
This commit is contained in:
ChengLei Shao 2023-03-28 12:26:30 +08:00 committed by GitHub
parent 708675deb9
commit e566d56c2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 118 additions and 6 deletions

View File

@ -1,5 +1,3 @@
import lodash from 'lodash';
export interface Reference {
sourceCollectionName: string;
sourceField: string;
@ -16,6 +14,8 @@ class ReferencesMap {
reference.onDelete = 'SET NULL';
}
reference.onDelete = reference.onDelete.toUpperCase();
const existReference = this.existReference(reference);
if (existReference && existReference.onDelete !== reference.onDelete) {
@ -59,6 +59,7 @@ class ReferencesMap {
removeReference(reference: Reference) {
const references = this.map.get(reference.targetCollectionName);
if (!references) {
return;
}

View File

@ -32,9 +32,21 @@ export class BelongsToManyField extends RelationField {
const onDelete = this.options.onDelete || 'CASCADE';
const targetAssociation = association.toTarget;
if (association.targetKey) {
targetAssociation.targetKey = association.targetKey;
}
const sourceAssociation = association.toSource;
if (association.sourceKey) {
sourceAssociation.targetKey = association.sourceKey;
}
return [
BelongsToField.toReference(db, association.toSource, onDelete),
BelongsToField.toReference(db, association.toTarget, onDelete),
BelongsToField.toReference(db, targetAssociation, onDelete),
BelongsToField.toReference(db, sourceAssociation, onDelete),
];
}
@ -59,6 +71,7 @@ export class BelongsToManyField extends RelationField {
name: through,
};
// set through collection schema
if (this.collection.collectionSchema()) {
throughCollectionOptions['schema'] = this.collection.collectionSchema();
}

View File

@ -1,11 +1,16 @@
import Database, { Collection as DBCollection } from '@nocobase/database';
import Database from '@nocobase/database';
import { MockServer, mockServer } from '@nocobase/test';
describe('reference integrity check', () => {
let db: Database;
let app: MockServer;
beforeEach(async () => {
app = mockServer();
app = mockServer({
database: {
tablePrefix: '',
},
});
await app.db.clean({ drop: true });
db = app.db;
});

View File

@ -0,0 +1,93 @@
import Database from '@nocobase/database';
import Application from '@nocobase/server';
import { createApp } from './index';
describe('reference integrity check', () => {
let db: Database;
let app: Application;
beforeEach(async () => {
app = await createApp({
database: {
tablePrefix: '',
},
});
db = app.db;
});
afterEach(async () => {
await app.destroy();
});
it('should cascade delete on belongs to many relation on collection', async () => {
const users = db.collection({
name: 'users',
fields: [
{
type: 'string',
name: 'name',
},
{
type: 'belongsToMany',
name: 'collections',
target: 'collections',
sourceKey: 'id',
foreignKey: 'user_id',
otherKey: 'collection_name',
targetKey: 'name',
onDelete: 'cascade',
through: 'users_collections',
},
],
});
db.extendCollection({
name: 'collections',
fields: [
{
type: 'belongsToMany',
name: 'users',
target: 'users',
onDelete: 'cascade',
through: 'users_collections',
sourceKey: 'name',
foreignKey: 'collection_name',
otherKey: 'user_id',
targetKey: 'id',
},
],
});
await db.sync();
const postsCollection = await db.getCollection('collections').repository.create({
values: {
name: 'posts',
},
});
const user1 = await users.repository.create({
values: {
name: 'foo',
collections: [postsCollection],
},
});
const throughCollection = db.getCollection('users_collections');
expect(await throughCollection.repository.count()).toEqual(1);
await user1.destroy();
expect(await throughCollection.repository.count()).toEqual(0);
const user2 = await users.repository.create({
values: {
name: 'bar',
collections: [postsCollection],
},
});
expect(await throughCollection.repository.count()).toEqual(1);
await postsCollection.destroy();
expect(await throughCollection.repository.count()).toEqual(0);
});
});