From 897bdb422815749be6bc41add5df969aedac90ff Mon Sep 17 00:00:00 2001 From: Dmitry Krasnoukhov Date: Sun, 20 Sep 2020 17:48:21 +0300 Subject: [PATCH] Do not assign lid when type does not match Add test for cache Alternaive solution to 7325 --- .../identifiers/polymorphic-scenarios-test.ts | 3 +++ packages/store/addon/-private/identifiers/cache.ts | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/packages/-ember-data/tests/integration/identifiers/polymorphic-scenarios-test.ts b/packages/-ember-data/tests/integration/identifiers/polymorphic-scenarios-test.ts index 5a5d29cc8a6..2e21124037d 100644 --- a/packages/-ember-data/tests/integration/identifiers/polymorphic-scenarios-test.ts +++ b/packages/-ember-data/tests/integration/identifiers/polymorphic-scenarios-test.ts @@ -83,6 +83,9 @@ module('Integration | Identifiers - single-table-inheritance polymorphic scenari const foundFerrari = await store.findRecord('car', '1'); assert.strictEqual(foundFerrari.constructor.modelName, 'ferrari', 'We found the right type'); + + const cachedFerrari = await store.peekRecord('ferrari', '1'); + assert.strictEqual(cachedFerrari.constructor.modelName, 'ferrari', 'We cached the right type'); }); test(`Identity of polymorphic relations can change type when in cache`, async function(assert) { diff --git a/packages/store/addon/-private/identifiers/cache.ts b/packages/store/addon/-private/identifiers/cache.ts index f9e7af7db72..a58f78174ea 100644 --- a/packages/store/addon/-private/identifiers/cache.ts +++ b/packages/store/addon/-private/identifiers/cache.ts @@ -343,6 +343,17 @@ export class IdentifierCache { let newId = coerceId(data.id); let existingIdentifier = detectMerge(this._cache.types, identifier, data, newId, this._cache.lids); + if (!existingIdentifier) { + // If the incoming type does not match the identifier type, we need to create an identifier for the incoming + // data so we can merge the incoming data with the existing identifier, see #7325 and #7363 + if (identifier.type !== data.type && data.type) { + let incomingDataResource = Object.assign({}, data); + // Need to strip the lid from the incomingData in order force a new identifier creation + delete incomingDataResource.lid; + existingIdentifier = this.getOrCreateRecordIdentifier(incomingDataResource); + } + } + if (existingIdentifier) { let keyOptions = getTypeIndex(this._cache.types, identifier.type); identifier = this._mergeRecordIdentifiers(keyOptions, identifier, existingIdentifier, data, newId as string);