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
.