在Ember-cli应用程序中保持ember-data中嵌入式关系的正确方法

时间:2014-08-14 10:10:00

标签: ember.js ember-data

我面临的情况是我需要将嵌入式关系持久化到数据库中。我在这个问题中描述了类似的情况。这是一个ember-cli项目。

我有两种模式:

//app/model/post.js
import DS from 'ember-data';

var Post = DS.Model.extend({
    entry:          DS.attr('string'),
    comments:       DS.hasMany('comment')
});

export default Post;

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

var Comment = DS.Model.extend({
    text: DS.attr('string'),
    post: DS.belongsTo('post')
});

export default Comment;

1序列化器:     //app/serializers/post.js     从' ember-data';

导入DS
export default DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {
  attrs: {
    comments: {
      embedded: 'always'
    }
  }
});

1路线:

//app/routes/index.js
import Ember from 'ember';

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

    setupController: function(controller, model) {
        var newComment = this.store.createRecord('comment', {});
        newComment.set('text', 'xxxx comment');

        model.get('comments').pushObject(newComment);
        model.save().then(function(){
            console.log(model.toJSON());
            comments = model.get('comments');
            comments.forEach(function(comment){
                console.log("Comment: " + comment.get('text'));
                console.log("Comment id: " + comment.get('id'));
            });
       });
    }
});

因此,model中的GET调用挂钩服务器返回:

// GET /posts/1
{
    "posts": {
        "id": "1",
        "entry": "This is first post",
        "comments": [
            {
                "id": "1",
                "post": "1",
                "text": "This is the first comment on first post"
            },
            {
                "id": "2",
                "post": "1",
                "text": "This is the second comment on first post"
            }
        ]
    }
}

setupController挂钩中,我向帖子添加了一条新评论并保存,它实际上向以下正文发送PUT请求:

// PUT /posts/1 -- Request
{
    "posts": {
        "id": "1",
        "entry": "This is first post",
        "comments": [
            {
                "id": "1",
                "post": "1",
                "text": "This is the first comment on first post"
            },
            {
                "id": "2",
                "post": "1",
                "text": "This is the second comment on first post"
            },
            {
                "post": "1",
                "text": "xxxx comment"
            }
        ]
    }
}

服务器返回以下输出:

// PUT /posts/1 -- Response
{
    "posts": {
        "id": "1",
        "entry": "This is first post",
        "comments": [
            {
                "id": "1",
                "post": "1",
                "text": "This is the first comment on first post"
            },
            {
                "id": "2",
                "post": "1",
                "text": "This is the second comment on first post"
            },
            {
                "id": "3",
                "post": "1",
                "text": "xxxx comment"
            }
        ]
    }
}

但现在在控制台日志中我得到以下输出:

Comment: This is the first comment on first post
Comment id: 1
Comment: This is the second comment on first post
Comment id: 2
Comment: xxxx comment
Comment id: 3
Comment: xxxx comment
Comment id: null

为什么返回id的新评论会添加到帖子的评论中,而不是替换评论? 我做错了什么或者我需要为此添加其他东西吗?

1 个答案:

答案 0 :(得分:1)

Ember Data没有确切的方法来识别用户试图保存的记录与不同用户试图保存的记录之间的区别。

所有可以安全地知道的是带有新ID的新记录回来了(因为之前记录中没有唯一标识符,并且您没有指定保存该确切记录)。

在非多用户世界中,它可以假设新记录应该替换现有记录,但嵌入式记录的东西不是那么聪明。

1。保存后删除记录(因为你知道它会被欺骗,hacky)

var comments = model.get('comments');
comments.pushObject(newComment);
model.save().then(function(){
  comments.popObject(newComment);
  newComment.deleteRecord(); // not really necessary
  ...
});

2。从评论的角度保存记录(最便宜和最干净,可能是一些额外的服务器端逻辑)

newComment.save();