如何使用 ember-data 将模型嵌入到模型(嵌套记录)中?

How to embed model in model (nest records) using ember-data?

我正在尝试使用 Ember-cli 在我的项目中设置嵌入式记录。 我无法让它工作,我尝试了 {embedded: "always", etc...} 的不同配置,但我得到的只是: Error: Assertion Failed: You must include an id for user in an object passed to push 请帮忙。

我正在使用

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: -------------------------------

我的 JSON 和 QuestionDefinition 是:

{
    "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
        }
    ]
}

问题定义模型是:

//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})
});

用户模型是:

//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'),
});

最后但同样重要的是,序列化程序:

//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);
    }
});

这个谜题在Stack的下20m可能没有答案,但答案在这里。 查看 questiondefinition serializer 可以看到有效负载被篡改,因为服务器响应保存在 'data' 属性 中。 神秘的错误 Error: Assertion Failed: You must include an id for user in an object passed to push 让我找到了 ember-data 的来源,在那里我发现我没有为用户模型准备序列化程序。所以 ember 只是想要用户属性,但它所能得到的只是 'data' 属性。所以 remember,总是让你的序列化程序保持最新。

就是这样!