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');
}
当我试图删除一个模型与另一个模型有 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');
}