Как сделать встроенные 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, а родитель не загрязнен
Что мне не хватает?
Ответы
Ответ 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' }
}
});