From 0094ded5c495dd4a619112f0ea38e37037309d8d Mon Sep 17 00:00:00 2001 From: Raymond Feng Date: Thu, 12 Sep 2019 09:35:45 -0700 Subject: [PATCH] fix(repository): allow model classes with recursive type references MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/strongloop/loopback-next/issues/3671#issuecomment-529376105 Co-authored-by: Miroslav Bajtoš --- .../legacy-juggler-bridge.unit.ts | 29 +++++++++++++++++++ .../src/repositories/legacy-juggler-bridge.ts | 4 +++ 2 files changed, 33 insertions(+) diff --git a/packages/repository/src/__tests__/unit/repositories/legacy-juggler-bridge.unit.ts b/packages/repository/src/__tests__/unit/repositories/legacy-juggler-bridge.unit.ts index ee7d4ac1dee7..63de1a675e16 100644 --- a/packages/repository/src/__tests__/unit/repositories/legacy-juggler-bridge.unit.ts +++ b/packages/repository/src/__tests__/unit/repositories/legacy-juggler-bridge.unit.ts @@ -210,6 +210,35 @@ describe('DefaultCrudRepository', () => { expect(User.definition.properties.roles.itemType).to.equal(Role); expect(User.definition.properties.address.type).to.equal(Address); }); + + it('handles recursive model references', () => { + @model() + class ReportState extends Entity { + @property({id: true}) + id: string; + + @property.array(ReportState, {}) + states: ReportState[]; + + @property({ + type: 'string', + }) + benchmarkId?: string; + + @property({ + type: 'string', + }) + color?: string; + + constructor(data?: Partial) { + super(data); + } + } + const repo = new DefaultCrudRepository(ReportState, ds); + const definition = repo.modelClass.definition; + const typeOfStates = definition.properties.states.type; + expect(typeOfStates).to.eql([repo.modelClass]); + }); }); it('shares the backing PersistedModel across repo instances', () => { diff --git a/packages/repository/src/repositories/legacy-juggler-bridge.ts b/packages/repository/src/repositories/legacy-juggler-bridge.ts index 5606125d0129..c2f6de4b666a 100644 --- a/packages/repository/src/repositories/legacy-juggler-bridge.ts +++ b/packages/repository/src/repositories/legacy-juggler-bridge.ts @@ -148,6 +148,10 @@ export class DefaultCrudRepository< return model as typeof juggler.PersistedModel; } + // To handle circular reference back to the same model, + // we create a placeholder model that will be replaced by real one later + dataSource.getModel(definition.name, true /* forceCreate */); + // We need to convert property definitions from PropertyDefinition // to plain data object because of a juggler limitation const properties: {[name: string]: object} = {};