EmberJS:如何删除具有 many-to-many 关系的记录

EmberJS: how to remove records with many-to-many relationship

当我试图删除一个模型与另一个模型有 many-to-many 关系的记录时,我偶然发现了一个问题。

我有书:

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');
    },

它正确地删除了这本书,对支持 REST 服务器的 DELETE 请求,但是对于所有在他们的 'books' collection 中有这本书的作者没有 PUT 请求。当我将视图更改为作者并返回书籍时,会创建一本虚拟书籍,其 ID 为我之前删除的那本书,并且 'authors' 也设置为旧作者,其他属性未定义。

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

你必须记住 DS.hasMany returns 一个承诺,所以在你使用它之前必须解决它:

  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');
    }
  },

看来我已经解决了。 第一个问题是,在我项目的服务器端,我错误地填充了数据 - 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');
}