Подтвердить что ты не робот

Как сделать встроенные hasMany отношения работать с данными ember

Я не могу получить 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 для двух записей не только родительской.

EDIT: Мой реальный вариант использования

1- Я только что создал данные ember от master

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();

отправляется POST для joincolumn, а родитель не загрязнен

Что мне не хватает?

4b9b3361

Ответ 1

У меня есть одна и та же проблема.

Об этой ошибке сообщается в трекер-хранилище данных ember. Следующий PR добавляет 2 неудачных теста, показывающих проблему: https://github.com/emberjs/data/pull/578

Кажется, что сейчас нет обходного пути.

EDIT:

sebastianseilund открыл PR 2 дня назад, что устраняет вашу проблему. Посмотрите на: https://github.com/emberjs/data/pull/629/files

Ответ 2

На главном, правильный API:

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

Двумя возможными значениями embedded являются:

  • load: дочерние записи внедряются при загрузке, но должны сохраняться как автономные записи. Чтобы это работало, дочерние записи должны иметь идентификатор.
  • always: дочерние записи внедряются при загрузке и сохраняются в одной записи. Это, конечно, влияет на загрязнение записей (если дочерняя запись изменяется, адаптер будет отмечать родительскую запись как грязную).

Если у вас нет пользовательского адаптера, вы можете вызвать map непосредственно на DS.RESTAdapter:

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

Ответ 3

Добавление обновления для этого случая, когда другие сталкиваются с этим сообщением и с трудом выясняют, что работает с текущей версией данных ember-данных.

Начиная с Ember Data 1.0.0, 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'
  })
});

Ответ 4

Это то, что сработало для меня (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' }
  }
});