jeudi 16 avril 2015

Ember Data Adapter Inconsistent Model Update on PUT Response

This will take a bit of explanation. Let's say I have a simple model...



// models/mymodel.js
import DS from 'ember-data';

export default DS.Model.extend({
myString: DS.attr('string'),
myBool: DS.attr('boolean')
});


...and a simple route...



// routes/myroute.js
import Ember from 'ember';

export default Ember.Route.extend({
model: function () {
return this.store.find('mymodel', 2);
}
});


...with an associated controller...



// controllers/myroute.js
import Ember from 'ember';

export default Ember.Controller.extend({
actions: {
myClick: function(){
this.model.set('myBool', true);
this.model.save();
}
}
});


...and template...



// templates/myroute.hbs
<p id="myp">{{model.myString}} {{if model.myBool "myBool"}}</p>
<button id="myclick" {{action "myClick"}}>Mybutton</button>


Here's a basic acceptance test for it all:



// tests/acceptance/myroute-test.js
// test setup code omitted for brevity
test('visiting /myroute', function (assert) {

// Here I'm just using mockjax to mock out the adapter response to the GET request for /mymodels/2
var upid = $.mockjax({
url: '/mymodels/2',
dataType: 'json',
responseText: {
mymodel: {
id: 2,
myString: 'oldString',
myBool: false
}
},
type: 'GET'
});

visit('/myroute');
andThen(function () {

// Check the state of the markup after initial model/template load
// myBool should be false, so the "myBool" string shouldn't be rendered
// myString has a value of "oldString", so we should be able to find that
var myp = find('#myp');
assert.ok(myp.html().indexOf("myBool") === -1); // This PASSES fine
assert.ok(myp.html().indexOf("oldString") > 0); // This PASSES fine

// Here I prepare the mock response for PUT /models/2
// NOTE that myBool has a value of false in the response
$.mockjax.clear(upid);
$.mockjax({
url: '/mymodels/2',
dataType: 'json',
responseText: {
mymodel: {
id: 2,
myString: 'newString',
myBool: false
}
},
type: 'PUT'
});


// Click the button which causes our PUT request
click('#myclick');
andThen(function () {

// PUT request finished...check the state now.
// The PUT response includes myBool=false, so the 'myBool' string should NOT be there. The response also includes myString='newString'
var myp = find('#myp');
assert.ok(myp.html().indexOf("newString") > 1); // This PASSES
assert.ok(myp.html().indexOf("myBool") === -1); // This FAILS!!
});
});
});


In short: when a user clicks the button, the controller sets myBool=true and saves the model. This sends a PUT request, after which the response is used to update myString to "newString", but for some reason myBool is NOT being updated to false from the response as I would expect. It's like the model is being partially-updated from the response. That is, myBool stays true after the controller sets it.


If there were something wrong with my code I'd expect both properties to not update. The fact that only the string property is updating based on the response is my main reason for thinking that this isn't a problem in my code.


I'm using ember-cli with Ember 1.11.1 and Ember Data 1.0.0-beta.16.1.


I was using the RESTAdapter here (I see the same behavior with ActiveModelAdapter).


I only noticed this "regression" after ember-data beta 16. Beta 15 behaved as I expected (i.e. no inconsistencies in the model updates).


Can anybody shed any light on this? Is this somehow an intended change in Ember-Data, or is it by-design?





Aucun commentaire:

Enregistrer un commentaire