I am trying to setup embedded records in my project using Ember-cli.
I can't get it working, I tried different configurations with {embedded: "always", etc...} but all I get is: Error: Assertion Failed: You must include an id
for user in an object passed to push
Please help.
I'm using
DEBUG: -------------------------------
DEBUG: Ember : 1.12.1
DEBUG: Ember Data : 1.13.4
DEBUG: jQuery : 2.1.4
DEBUG: Ember Simple Auth : 0.8.0
DEBUG: -------------------------------
My JSON with QuestionDefinitions is:
{
"data": [
{
"created": 1439824135440,
"updated": 1439824135440,
"userID": 20,
"user": {
"password": null,
"created": null,
"updated": null,
"photoID": null,
"photo": null,
"email": "super@duper.com",
"emailConfirmed": false,
"phoneNumber": null,
"phoneNumberConfirmed": false,
"accessFailedCount": 0,
"id": 20,
"userName": "qwerty"
},
"addCategoriesIDs": [],
"removeCategoriesIDs": [],
"recommendations": [],
"removeRecommendstionIDs": [],
"patternAnswers": [],
"removePatternAnswerIDs": [],
"hint": null,
"version": 1,
"commonVersion": 2,
"id": 1,
"questionText": "Test?",
"weight": 0,
"answerType": 0,
"status": 0,
"estimatedTime": null,
"private": false
},
{
"created": 1439824143340,
"updated": 1439824143340,
"userID": 20,
"user": {
"password": null,
"created": null,
"updated": null,
"photoID": null,
"photo": null,
"email": "super@duper.com",
"emailConfirmed": false,
"phoneNumber": null,
"phoneNumberConfirmed": false,
"accessFailedCount": 0,
"id": 20,
"userName": "qwerty"
},
"addCategoriesIDs": [],
"removeCategoriesIDs": [],
"recommendations": [],
"removeRecommendstionIDs": [],
"patternAnswers": [],
"removePatternAnswerIDs": [],
"hint": null,
"version": 1,
"commonVersion": 3,
"id": 2,
"questionText": "Test?",
"weight": 0,
"answerType": 0,
"status": 0,
"estimatedTime": null,
"private": false
}
]
}
QuestionDefinition model is:
//app/models/questiondefinition.js
import Ember from 'ember';
import DS from "ember-data";
export default DS.Model.extend({
//id : DS.attr('string'), //sie nie uzywa
created : DS.attr('pl-date'),
updated : DS.attr('pl-date'),
userID : DS.attr('number'),
user : DS.belongsTo('user',{async: false, embedded: 'always'}),
//hint : DS.attr('string'),
hint : null,
version : DS.attr('number'),
commonVersion : DS.attr('number'),
questionText : DS.attr('string'),
weight : DS.attr('number'),
answerType : 0,
status : 0,
estimatedTime : DS.attr('number'),
"private" : DS.attr('boolean'),
questionDefLegalBasis: function () {
return this.get('questionText').length % 2 > 0;
}.property('questionText'),
/**
* One-to-many
*/
patternAnswers : DS.hasMany('patternanswer'),
recommendations: DS.hasMany('recommendation'),
categories : DS.hasMany('questiondefinitioncategory', {async: true}),
comments : DS.hasMany('questiondefinitioncomment', {async: true})
});
User model is:
//app/models/user.js
import Ember from 'ember';
import DS from "ember-data";
export default DS.Model.extend({
"password": DS.attr('string'),
"created": DS.attr('pl-date'),
"updated": DS.attr('pl-date'),
"photoID": DS.attr('number'),
"photo": DS.attr('string'),
"email": DS.attr('string'),
"emailConfirmed": DS.attr('boolean'),
"phoneNumber": DS.attr('string'),
"phoneNumberConfirmed": DS.attr('boolean'),
"accessFailedCount": DS.attr('number'),
"userName": DS.attr('string'),
/**
* One-to-many
*/
//questionDefinitions : DS.hasMany('questiondefinition'),
questionDefinitionComments : DS.hasMany('questiondefinitioncomment'),
patternAnswers : DS.hasMany('patternanswer'),
});
And last but not least, serializer:
//app/serializers/questiondefinition.js:4
import DS from "ember-data";
function removeErrorsIfEmtpy(payload) {
if (typeof payload.errors !== 'undefined' && payload.errors.length === 0) {
delete payload.errors;
}
}
export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs : {
user: {embedded: 'always',
serialize : 'record',
deserialize: 'record'
}
//comments: { serialize: 'ids' }
},
extractArray : function (store, type, payload) {
payload.questiondefinitions = payload.data;
delete payload.data;
removeErrorsIfEmtpy(payload);
//console.log(arguments);
//return this._super(store, type, payload);
return this._super.apply(this, arguments);
},
extractSingle: function (store, primaryTypeClass, payload, recordId) {
payload.questiondefinition = payload.data;
delete payload.data;
removeErrorsIfEmtpy(payload);
//return this._super(store, primaryTypeClass, payload, recordId);
return this._super.apply(this, arguments);
}
});
This enigmatic question could be without answer to the next 20m of Stack, but here is the answer.
Looking at the questiondefinition serializer
one sees that there is tampering with payload because server responses with objects kept in 'data' property.
The enigmatic error Error: Assertion Failed: You must include an id for user in an object passed to push led me to the source of ember-data where I find out that I didn't prepared serializer for user model. So ember just wanted the user properties but all it could get it was 'data' property. So remember, always keep your serializers up to date.
That's IT!