EmberJS:如何删除具有多对多关系的记录

时间:2015-01-21 23:32:26

标签: ember.js many-to-many ember-data

当我试图移除一个模型与另一个模型处于多对多关系的记录时,我偶然发现了一个问题。

我有书:

App.Book = DS.Model.extend({
    title: DS.attr('string'),
    isbn: DS.attr('string'),
    category: DS.attr('string'),
    publishDate: DS.attr('date'),
    authors: DS.hasMany('author', {inverse: 'books'})
});

以及作者:

App.Author = DS.Model.extend({
    firstName: DS.attr('string'),
    lastName: DS.attr('string'),
    birthDate: DS.attr('date'),
    books: DS.hasMany('book', {async: true, inverse: 'authors'})
});

我正在删除这样的书:

actions: {
    delete: function (book) {
        var authors = book.get('authors')
        authors.forEach(function(author) {
            var books = author.get('books')
            books.forEach(function(book){
                console.log(book.toJSON());
            })
            books.removeObject(book);
            //books.save doesn't work
        })
        book.destroyRecord();
        this.transitionToRoute('books.index');
    },

它正确地删除了这本书,DELETE请求支持REST服务器,但没有PUT请求所有那些在他们的书中有这本书的作者。采集。当我将视图更改为作者并返回书籍时,会创建一个虚拟书籍,其中包含我之前删除的ID和“作者”。设置为旧作者,其他属性未定义。

如何正确删除图书以便更新作者?

2 个答案:

答案 0 :(得分:1)

您必须记住DS.hasMany会返回一个承诺,因此必须先解决它才能使用它:

  actions: {
    delete: function (book) {
     if (!book.get('isDeleted')) {
       book.destroyRecord()
         .catch(function(error) {
           console.log(error);
           book.rollback();
         })
         .then(function(book) {
           book.get('authors').then(function (authors) {
             authors.mapBy('books').forEach(function(books) {
                if (typeof books.then === "function") {
                  books.then(function(books) {
                    books.removeObject(book);
                  });
                } else {
                  books.removeObject(book);
                }
             });
           });
         });
      }

      this.transitionToRoute('books.index');
    }
  },

答案 1 :(得分:0)

看起来我已经解决了。 第一个问题是,在我的项目的服务器端,我错误地填充了数据 - 这些ID是错误的,并且与它们之间的关系不匹配。

另一件事是保存不正确的对象。我试图只保存带有书籍的数组,不得不保存整个作者(实际上这是有道理的)。工作行动是:

console.log('Removing book: ' + book.get('id') + book.get('title'));
var authors = book.get('authors')
var id = book.get('id');
authors.forEach(function (author) {
   var books = author.get('books').removeObject(book);
   author.save();
})
book.destroyRecord();
this.transitionToRoute('books.index');

我唯一的疑问是在BookController中定义了删除操作,其模型是我试图删除的书,因此我不应该将该书放在参数中,而是使用控制器的模型。我刚刚发现只需删除参数并将书声明为this.get('model')即可轻松实现,这就是为什么最终的工作解决方案是:

delete: function () {
    var book = this.get('model')
    console.log('Removing book: ' + book.get('id') + book.get('title'));
    var authors = book.get('authors')
    var id = book.get('id');
    authors.forEach(function (author) {
        var books = author.get('books').removeObject(book);
        author.save();
    })
    book.destroyRecord();
    this.transitionToRoute('books.index');
}