17

我无法embedded hasMany正确使用 ember 数据。

我有这样的东西

App.Post = DS.Model.extend({
  comments: DS.hasMany('App.Comment')
});

App.Comment = DS.Model.extend({
  post: DS.hasMany('App.Post'),
  name: attr('string')
});

我的 API 返回以下内容GET /post

[
  {
   id: 1
   comments: [{name: 'test'}, {name: 'test2'}]
  },
  ...
]

我需要发送这个POST /post

[
  {
    comments: [{name: 'test'}, {name: 'test2'}]
  },
  ...
]

我想使用 Ember 模型并让他们提出适当的请求:

var post = App.store.createRecord(App.Post, hash_post_without_comments);
post.get('comments').createRecord(hash_comment);

App.store.commit(); // This should call the POST api 

var posts = App.store.find(App.Post); // This should call the GET api 

当我尝试类似的东西post: DS.hasMany('App.Post', {embedded: true})时,GET 正在工作,但 POST 正在尝试为这两条记录创建一个 POST,而不仅仅是父记录。

编辑:我的真实用例

1-我刚刚从 master 构建了 ember 数据

2-我的适配器:RESTAdapter

3- 序列化器:JSONSerializer

4-我添加了

App.MyAdapter.map('App.Join', {
    columns: { embedded: 'always' }
});

5- 我的模型是:

App.Join = DS.Model.extend({
    rowCount: DS.attr('number'),
    columns: DS.hasMany('App.JoinColumn'),
});

App.JoinColumn = DS.Model.extend({
    join: DS.belongsTo('App.Join')
});

6- 何时:

var a = App.Join.find(1);
a.get('columns').createRecord({});
App.store.commit();

joincolumn 的 POST 已发送且父级不脏

我错过了什么?

4

4 回答 4

46

在 master 上,正确的 API 是:

App.Adapter.map('App.Post', {
  comments: { embedded: 'always' }
});

的两个可能值embedded是:

  • load:加载时嵌入子记录,但应保存为独立记录。为了使它起作用,子记录必须有一个 ID。
  • always:加载时嵌入子记录,并保存嵌入在同一记录中。当然,这会影响记录的脏度(如果子记录发生更改,适配器会将父记录标记为脏)。

如果您没有自定义适配器,则可以map直接调用DS.RESTAdapter

DS.RESTAdapter.map('App.Post', {
  comments: { embedded: 'always' }
});
于 2013-01-14T18:42:11.833 回答
7

我有完全一样的问题。

此错误已在 ember 数据问题跟踪器上报告。以下 PR 添加了 2 个显示问题的失败测试:https ://github.com/emberjs/data/pull/578

现在似乎没有解决方法。

编辑:

sebastianseilund 2 天前打开了一个 PR,它解决了您的问题。看看:https ://github.com/emberjs/data/pull/629/files

于 2013-01-16T16:05:10.683 回答
5

对此添加更新,以防其他人遇到此帖子,并且很难弄清楚当前版本的 ember-data 的工作原理。

从 Ember Data 1.0.0.beta.7 开始,您需要覆盖序列化程序上的适当方法。这是一个例子:

1)重新打开序列化器(归功于这篇文章):

DS.RESTSerializer.reopen({
  serializeHasMany: function(record, json, relationship) {
    var hasManyRecords, key;
    key = relationship.key;
    hasManyRecords = Ember.get(record, key);
    if (hasManyRecords && relationship.options.embedded === "always") {
      json[key] = [];
      hasManyRecords.forEach(function(item, index) {
        // use includeId: true if you want the id of each model on the hasMany relationship
        json[key].push(item.serialize({ includeId: true }));
      });
    } else {
      this._super(record, json, relationship);
    }
  }
});

2)embedded: 'always'在模型上的关系中添加选项:

App.Post = DS.Model.extend({
  comments: DS.hasMany('comment', {
    embedded: 'always'
  })
});
于 2014-03-04T20:47:39.510 回答
5

这对我有用(Ember 1.5.1+pre.5349ffcb,Ember Data 1.0.0-beta.7.f87cba88):

App.Post = DS.Model.extend({
  comments: DS.hasMany('comment', { embedded: 'always' })
});

App.PostSerializer = DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {
  attrs: {
    comments: { embedded: 'always' }
  }
});
于 2014-05-13T20:42:50.370 回答