问题
What is the ember-cli best practice to deleteRecord() on a model that belongsTo multiple models? Do I have to manually clean up relationships on the parents?
Migrating from ember to ember-cli I am having new trouble with deleteRecord() for a model 'star' that belongsTo multiple models, 'post' and 'user'. Before moving to ember cli it was working with this solution.
The previous solution's delete action fails in the current ember-cli with errors and never calls the api. TypeError: Cannot read property 'modelFor' of undefined
and Uncaught Error: Assertion Failed: TypeError: Cannot read property 'modelFor' of undefined
at the line
var inverse = relationship.parentType.inverseFor(name);
// name is the string 'post'
Now I'm starting simple again. Here is a simple example of what I'm trying. Maybe I am missing something with es6, explicit inverses, or using needs:
?
http://localhost:4200/post/1
models
// models/star.js
import DS from 'ember-data';
export default DS.Model.extend({
created: DS.attr('date'),
post: DS.belongsTo('post', {
async: true,
inverse: 'stars'
}),
user: DS.belongsTo('user', {
async: true,
inverse: 'stars'
})
});
// models/post.js
import DS from 'ember-data';
export default DS.Model.extend({
headline: DS.attr(),
body: DS.attr(),
stars: DS.hasMany('star', { async: true })
});
// models/users.js
import DS from 'ember-data';
export default DS.Model.extend({
username: DS.attr(),
stars: DS.hasMany('star', { async: true })
});
controller
//controllers/post.js
import Ember from 'ember';
export default Ember.ObjectController.extend({
actions: {
createStar: function(){
var self=this,
post = this.get('model'),
user = this.store.find('user', 2),
star;
user.then( function(user){
star = self.get('store').createRecord('star', {
post: post,
user: user
});
star.save().then( function(star){
post.get('stars').then( function(stars){
stars.pushObject(star);
});
user.get('stars').then( function(stars){
stars.pushObject(star);
});
});
});
},
deleteStar: function() {
var user = this.store.find('user', 2),
self = this;
user.then( function(user){
var filtered = self.get('stars').filterProperty('user.id', user.id);
var star = filtered[0];
star.deleteRecord();
star.save();
});
return(false);
}
}
});
Update: Alternate deleteStar
post
controller action re: @jjwon
deleteStar: function() {
var user = this.store.find('user', 2),
self = this;
user.then( function(user){
var stars = self.get('stars').then( function(items){
// log the post's stars before delete
items.forEach(function(item) {
console.log(item);
});
var filtered = items.filterBy('user.id', user.id);
var star = filtered.get('firstObject');
star.deleteRecord();
star.save().then(function(){
// log the post's stars after delete
items.forEach(function(item) {
console.log(item);
});
});
});
});
return(false);
}
Interestingly I found that if I add a star, reload the page, then delete it, that the star is successfully removed from the post's stars. Great!
But if I add a star and remove it without reloading, there is still a reference to the removed star with its id
among the post's stars. Looking in the console, the removed star object is still referenced by the post with its id
, but the user
and post
attributes are undefined
.
回答1:
stars
is an async attribute of user
. Therefore, when you have:
var filtered = self.get('stars').filterProperty('user.id', user.id);
var star = filtered[0];
star.deleteRecord();
star.save();
filtered
might be a promise, so this might not be working as expected. Also, I'm not too familiar with filterProperty, but you don't have an attribute called user.id
so it seems like that might be returning an empty list?
回答2:
For now I'm cleaning up the relationships on the parents very manually. This works but isn't ideal.
deleteStar: function() {
var user = this.store.find('user', 2),
self = this;
user.then( function(user){
var star = self.get('stars').filterBy('user.id', user.id).get('firstObject');
// clean up relationships on parents very manually
// user.stars
user.get('stars').removeObject(star);
// posts.stars
self.get('stars').removeObject(star);
star.deleteRecord();
star.save();
});
return(false);
}
来源:https://stackoverflow.com/questions/24644902/deleterecord-with-multiple-belongsto-relationships-in-ember-cli