From f5e9d622f8ab3d7e38f3cb908e2026e3f6a2917f Mon Sep 17 00:00:00 2001 From: Stefan Penner Date: Mon, 17 Apr 2017 21:03:46 -0700 Subject: [PATCH] [BUGFIX beta] [fixes #4509] createRecord initializes correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * by the name Model.prototype.init is called, internal model’s data has been loaded * do no emit extra change events during `createRecord` as the attributes are the initial state. --- addon/-private/system/model/internal-model.js | 6 +++++- addon/-private/system/store.js | 10 +-------- tests/unit/model-test.js | 21 +++++++++++++++++++ 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/addon/-private/system/model/internal-model.js b/addon/-private/system/model/internal-model.js index 0d1c8168491..3fdf3d0bd0d 100644 --- a/addon/-private/system/model/internal-model.js +++ b/addon/-private/system/model/internal-model.js @@ -319,7 +319,7 @@ export default class InternalModel { return this.currentState.dirtyType; } - getRecord() { + getRecord(properties) { if (!this._record && !this._isDematerializing) { heimdall.increment(materializeRecord); let token = heimdall.start('InternalModel.getRecord'); @@ -335,6 +335,10 @@ export default class InternalModel { adapterError: this.error }; + if (typeof properties === 'object' && properties !== null) { + assign(createOptions, properties); + } + if (setOwner) { // ensure that `getOwner(this)` works inside a model instance setOwner(createOptions, getOwner(this.store)); diff --git a/addon/-private/system/store.js b/addon/-private/system/store.js index f897e518f23..2ac7e41cdfb 100644 --- a/addon/-private/system/store.js +++ b/addon/-private/system/store.js @@ -365,16 +365,8 @@ Store = Service.extend({ properties.id = coerceId(properties.id); let internalModel = this._buildInternalModel(normalizedModelName, properties.id); - let record = internalModel.getRecord(); - - // Move the record out of its initial `empty` state into - // the `loaded` state. - // TODO @runspired this seems really bad, store should not be changing the state internalModel.loadedData(); - - // Set the properties specified on the record. - // TODO @runspired this is probably why we do the bad thing above - record.setProperties(properties); + let record = internalModel.getRecord(properties); // TODO @runspired this should also be coalesced into some form of internalModel.setState() internalModel.eachRelationship((key, descriptor) => { diff --git a/tests/unit/model-test.js b/tests/unit/model-test.js index e3c92e6ff97..297412539a7 100644 --- a/tests/unit/model-test.js +++ b/tests/unit/model-test.js @@ -1329,6 +1329,27 @@ test('toJSON looks up the JSONSerializer using the store instead of using JSONSe assert.deepEqual(json, {}); }); +test('internalModel is ready by `init`', function(assert) { + assert.expect(2); + let nameDidChange = 0; + + const Person = DS.Model.extend({ + name: DS.attr('string'), + + init() { + this._super(...arguments); + this.set('name', 'my-name-set-in-init'); + }, + + nameDidChange: Ember.observer('name', () => nameDidChange++) + }); + + let { store } = setupStore({ person: Person }); + + assert.equal(nameDidChange, 0, 'observer should not trigger on create'); + let person = run(() => store.createRecord('person')); + assert.equal(person.get('name'), 'my-name-set-in-init'); +}); test('accessing attributes in the initializer should not throw an error', function(assert) { assert.expect(1);