Skip to content

Commit

Permalink
[BUGFIX beta] Fix resetting of properties to in-flight values
Browse files Browse the repository at this point in the history
Changing the value of an in-flight property, then changing back, had the
side effect that the record would be marked dirty once the save
completed.

`changedAttributes` would report that `name` had been changed from
'Thomas' to 'Thomas'

This is because the attr computed was only checking to see if the value
was being reset to the canonical value, not if it was being reset to the
in-flight value
  • Loading branch information
courajs committed May 10, 2016
1 parent afeb5e0 commit 8046c48
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
9 changes: 8 additions & 1 deletion addon/attr.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,16 +140,23 @@ export default function attr(type, options) {
set(key, value) {
var internalModel = this._internalModel;
var oldValue = getValue(internalModel, key);
var originalValue;

if (value !== oldValue) {
// Add the new value to the changed attributes hash; it will get deleted by
// the 'didSetProperty' handler if it is no different from the original value
internalModel._attributes[key] = value;

if (key in internalModel._inFlightAttributes) {
originalValue = internalModel._inFlightAttributes[key]
} else {
originalValue = internalModel._data[key]
}

this._internalModel.send('didSetProperty', {
name: key,
oldValue: oldValue,
originalValue: internalModel._data[key],
originalValue: originalValue,
value: value
});
}
Expand Down
45 changes: 45 additions & 0 deletions tests/unit/model-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,51 @@ test("resetting a property on a record cause it to become clean again", function
});
});

test("resetting a property to the current in-flight value causes it to become clean when the save completes", function(assert) {
assert.expect(4);

var person, finishSaving;

env.adapter.updateRecord = function(store, type, snapshot) {
// Make sure the save is async
return new Ember.RSVP.Promise(function(resolve, reject) {
finishSaving = resolve;
});
};

run(function() {
store.push({
data: {
type: 'person',
id: '1',
attributes: {
name: 'Tom'
}
}
});
person = store.peekRecord('person', 1);
person.set('name', "Thomas");

person.save();
});

run(function() {
assert.equal(person.get('name'), "Thomas");

person.set('name', 'Tomathy');
assert.equal(person.get('name'), "Tomathy");

person.set('name', 'Thomas');
assert.equal(person.get('name'), "Thomas");

finishSaving();
});

run(function() {
assert.equal(person.get('hasDirtyAttributes'), false, "The person is now clean");
});
});

test("a record becomes clean again only if all changed properties are reset", function(assert) {
assert.expect(5);
env.adapter.shouldBackgroundReloadRecord = () => false;
Expand Down

0 comments on commit 8046c48

Please sign in to comment.