Skip to content

Commit

Permalink
[BUGFIX beta] Make _recordData lazy
Browse files Browse the repository at this point in the history
  • Loading branch information
hjdivad committed Nov 30, 2018
1 parent 187000e commit 4b070d6
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 1 deletion.
21 changes: 20 additions & 1 deletion addon/-private/system/model/internal-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export default class InternalModel {
this.modelName = modelName;
this.clientId = clientId;

this._recordData = store._createRecordData(modelName, id, clientId, this);
this.__recordData = null;

// this ensure ordered set can quickly identify this as unique
this[Ember.GUID_KEY] = InternalModelReferenceId++ + 'internal-model';
Expand Down Expand Up @@ -144,6 +144,17 @@ export default class InternalModel {
return this._recordReference;
}

get _recordData() {
if (this.__recordData === null) {
this._recordData = this.store._createRecordData(this.modelName, this.id, this.clientId, this);
}
return this.__recordData;
}

set _recordData(newValue) {
this.__recordData = newValue;
}

get _recordArrays() {
if (this.__recordArrays === null) {
this.__recordArrays = new OrderedSet();
Expand Down Expand Up @@ -764,6 +775,10 @@ export default class InternalModel {

hasChangedAttributes() {
heimdall.increment(hasChangedAttributes);
if (this.isLoading()) {
// no need to instantiate _recordData in this case
return false;
}
return this._recordData.hasChangedAttributes();
}

Expand All @@ -776,6 +791,10 @@ export default class InternalModel {
*/
changedAttributes() {
heimdall.increment(changedAttributes);
if (this.isLoading()) {
// no need to calculate changed attributes when calling `findRecord`
return {};
}
return this._recordData.changedAttributes();
}

Expand Down
59 changes: 59 additions & 0 deletions tests/integration/records/record-data-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { run } from '@ember/runloop';
import { attr, belongsTo, hasMany } from '@ember-decorators/data';
import { assign } from '@ember/polyfills';
import { RecordData, recordDataFor } from 'ember-data/-private';
import { resolve } from 'rsvp';

class Person extends Model {
@hasMany('pet', { inverse: null, async: false })
Expand Down Expand Up @@ -216,4 +217,62 @@ module('RecordData Compatibility', function(hooks) {
assert.ok(false, 'expected `unloadRecord()` not to throw');
}
});

test(`store.findRecord does not eagerly instantiate record data`, async function(assert) {
let recordDataInstances = 0;
class TestRecordData extends CustomRecordData {
constructor() {
super(...arguments);
++recordDataInstances;
}
}

store.createRecordDataFor = function(modelName, id, lid, storeWrapper) {
return new TestRecordData(modelName, id, lid, storeWrapper);
};
this.owner.register(
'adapter:pet',
class TestAdapter {
static create() {
return new TestAdapter(...arguments);
}

findRecord() {
assert.equal(
recordDataInstances,
0,
'no instance created from findRecord before adapter promise resolves'
);

return resolve({
data: {
id: '1',
type: 'pet',
attributes: {
name: 'Loki',
},
},
});
}
}
);
this.owner.register(
'serializer:pet',
class TestSerializer {
static create() {
return new TestSerializer(...arguments);
}

normalizeResponse(store, modelClass, payload) {
return payload;
}
}
);

assert.equal(recordDataInstances, 0, 'initially no instances');

await store.findRecord('pet', '1');

assert.equal(recordDataInstances, 1, 'record data created after promise fulfills');
});
});

0 comments on commit 4b070d6

Please sign in to comment.