diff --git a/packages/-ember-data/tests/integration/adapter/record-persistence-test.js b/packages/-ember-data/tests/integration/adapter/record-persistence-test.js index 9a4df03c339..6e05d16c33c 100644 --- a/packages/-ember-data/tests/integration/adapter/record-persistence-test.js +++ b/packages/-ember-data/tests/integration/adapter/record-persistence-test.js @@ -318,4 +318,46 @@ module('integration/adapter/record_persistence - Persisting Records', function(h assert.strictEqual(tom.isDeleted, true, 'Tom is marked as deleted'); assert.strictEqual(yehuda.isDeleted, true, 'Yehuda is marked as deleted'); }); + + test('Create record response does not have to include the type property', async function(assert) { + assert.expect(2); + + const Person = Model.extend({ + updatedAt: attr('string'), + name: attr('string'), + firstName: attr('string'), + lastName: attr('string'), + }); + + const ApplicationAdapter = Adapter.extend({ + shouldBackgroundReloadRecord: () => false, + }); + + this.owner.register('model:person', Person); + this.owner.register('adapter:application', ApplicationAdapter); + this.owner.register( + 'serializer:application', + JSONAPISerializer.extend({ + normalizeResponse: (store, primaryModelClass, payload, id, requestType) => { + return payload; + }, + }) + ); + + let store = this.owner.lookup('service:store'); + let adapter = store.adapterFor('application'); + + let tom; + + adapter.createRecord = function(_store, type, snapshot) { + assert.strictEqual(type, Person, "The type of the record is 'Person'"); + assert.strictEqual(snapshot.record, tom, 'The record in the snapshot is the correct one'); + + return resolve({ data: { id: '1' } }); + }; + + tom = store.createRecord('person', { name: 'Tom Dale' }); + + return await tom.save(); + }); }); diff --git a/packages/store/addon/-private/identifiers/cache.ts b/packages/store/addon/-private/identifiers/cache.ts index 417ad812d7a..d262a18e677 100644 --- a/packages/store/addon/-private/identifiers/cache.ts +++ b/packages/store/addon/-private/identifiers/cache.ts @@ -486,7 +486,7 @@ function performRecordIdentifierUpdate( updateFn: UpdateMethod ) { let { id, lid } = data; - let type = normalizeModelName(data.type); + let type = data.type && normalizeModelName(data.type); if (DEBUG) { // get the mutable instance behind our proxy wrapper @@ -517,7 +517,7 @@ function performRecordIdentifierUpdate( } // TODO consider just ignoring here to allow flexible polymorphic support - if (type !== identifier.type) { + if (type && type !== identifier.type) { throw new Error( `The 'type' for a RecordIdentifier cannot be updated once it has been set. Attempted to set type for '${wrapper}' to '${type}'.` ); @@ -551,14 +551,14 @@ function detectMerge( return existingIdentifier !== undefined ? existingIdentifier : false; } else { - let newType = normalizeModelName(data.type); + let newType = data.type && normalizeModelName(data.type); // If the ids and type are the same but lid is not the same, we should trigger a merge of the identifiers if (id !== null && id === newId && newType === type && data.lid && data.lid !== lid) { let existingIdentifier = lids[data.lid]; return existingIdentifier !== undefined ? existingIdentifier : false; // If the lids are the same, and ids are the same, but types are different we should trigger a merge of the identifiers - } else if (id !== null && id === newId && newType !== type && data.lid && data.lid === lid) { + } else if (id !== null && id === newId && newType && newType !== type && data.lid && data.lid === lid) { let keyOptions = getTypeIndex(typesCache, newType); let existingIdentifier = keyOptions.id[id]; return existingIdentifier !== undefined ? existingIdentifier : false;