From d86da180066ae788ce945e3db4dc14c2924044bb Mon Sep 17 00:00:00 2001 From: ChengLei Shao Date: Sat, 3 Jun 2023 00:06:54 +0800 Subject: [PATCH] fix(database): missing reference when rewrite parent field (#1977) --- .../inhertits/collection-inherits.test.ts | 54 +++++++++++++++++++ .../database/src/fields/belongs-to-field.ts | 10 ++-- .../src/fields/belongs-to-many-field.ts | 3 +- .../database/src/fields/has-many-field.ts | 2 +- .../core/database/src/fields/has-one-field.ts | 2 +- 5 files changed, 64 insertions(+), 7 deletions(-) diff --git a/packages/core/database/src/__tests__/inhertits/collection-inherits.test.ts b/packages/core/database/src/__tests__/inhertits/collection-inherits.test.ts index 3884cf14a..d82220366 100644 --- a/packages/core/database/src/__tests__/inhertits/collection-inherits.test.ts +++ b/packages/core/database/src/__tests__/inhertits/collection-inherits.test.ts @@ -16,6 +16,60 @@ pgOnly()('collection inherits', () => { await db.close(); }); + it('should not remove parent field reference map after child rewrite field', async () => { + const through = db.collection({ + name: 'through', + fields: [{ name: 'name', type: 'string' }], + }); + + const rootCollection = db.collection({ + name: 'root', + fields: [ + { name: 'name', type: 'string' }, + { + name: 'targets', + type: 'belongsToMany', + target: 'root-target', + through: 'through', + foreignKey: 'rootId', + otherKey: 'targetId', + }, + ], + }); + + const rootTarget = db.collection({ + name: 'root-target', + fields: [{ name: 'name', type: 'string' }], + }); + + await db.sync({ force: true }); + + expect(db.referenceMap.getReferences('root-target')).toHaveLength(1); + + const child = db.collection({ + name: 'child', + inherits: ['root'], + }); + + const childTarget = db.collection({ + name: 'child-target', + inherits: ['root-target'], + }); + + await child.setField('targets', { + name: 'targets', + type: 'belongsToMany', + target: 'child-target', + through: 'through', + foreignKey: 'rootId', + otherKey: 'targetId', + }); + + await db.sync(); + + expect(db.referenceMap.getReferences('root-target')).toHaveLength(1); + }); + it('should list data filtered by child type', async () => { const rootCollection = db.collection({ name: 'root', diff --git a/packages/core/database/src/fields/belongs-to-field.ts b/packages/core/database/src/fields/belongs-to-field.ts index b4d552d88..e8f32e9f7 100644 --- a/packages/core/database/src/fields/belongs-to-field.ts +++ b/packages/core/database/src/fields/belongs-to-field.ts @@ -5,12 +5,12 @@ import { checkIdentifier } from '../utils'; import { BaseRelationFieldOptions, RelationField } from './relation-field'; export class BelongsToField extends RelationField { + static type = 'belongsTo'; + get dataType() { return 'BelongsTo'; } - static type = 'belongsTo'; - get target() { const { target, name } = this.options; return target || Utils.pluralize(name); @@ -78,7 +78,9 @@ export class BelongsToField extends RelationField { this.collection.addIndex([this.options.foreignKey]); - this.database.referenceMap.addReference(this.reference(association)); + const reference = this.reference(association); + + this.database.referenceMap.addReference(reference); return true; } @@ -103,7 +105,7 @@ export class BelongsToField extends RelationField { } const association = collection.model.associations[this.name]; - if (association) { + if (association && !this.options.inherit) { const reference = this.reference(association); this.database.referenceMap.removeReference(reference); } diff --git a/packages/core/database/src/fields/belongs-to-many-field.ts b/packages/core/database/src/fields/belongs-to-many-field.ts index 1addf1747..adae1630d 100644 --- a/packages/core/database/src/fields/belongs-to-many-field.ts +++ b/packages/core/database/src/fields/belongs-to-many-field.ts @@ -135,7 +135,8 @@ export class BelongsToManyField extends RelationField { // 删掉 model 的关联字段 const association = collection.model.associations[this.name]; - if (association) { + + if (association && !this.options.inherit) { this.references(association).forEach((reference) => this.database.referenceMap.removeReference(reference)); } diff --git a/packages/core/database/src/fields/has-many-field.ts b/packages/core/database/src/fields/has-many-field.ts index 2b00815d8..d6b7b7c42 100644 --- a/packages/core/database/src/fields/has-many-field.ts +++ b/packages/core/database/src/fields/has-many-field.ts @@ -175,7 +175,7 @@ export class HasManyField extends RelationField { const association = collection.model.associations[this.name]; - if (association) { + if (association && !this.options.inherit) { this.database.referenceMap.removeReference(this.reference(association)); } diff --git a/packages/core/database/src/fields/has-one-field.ts b/packages/core/database/src/fields/has-one-field.ts index 3fd83df7b..7e8a6404c 100644 --- a/packages/core/database/src/fields/has-one-field.ts +++ b/packages/core/database/src/fields/has-one-field.ts @@ -181,7 +181,7 @@ export class HasOneField extends RelationField { const association = collection.model.associations[this.name]; - if (association) { + if (association && !this.options.inherit) { this.database.referenceMap.removeReference(this.reference(association)); }