deleteRecord with multiple belongsTo relationships in ember-cli

依然范特西╮ 提交于 2019-12-11 08:43:43

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!