2013-03-02 58 views
11

我有兩個型號:刪除與Ember數據關聯的模型

App.User = DS.Model.create({ 
    comments: DS.hasMany('App.Comment') 
}); 

App.Comment = DS.Model.create({ 
    user: DS.belongsTo('App.User') 
}); 

當用戶被刪除,它還​​會刪除其在後端的所有意見,所以我應該從客戶端的身份將其刪除地圖。

我從另一個地方列出了系統上的所有評論,所以在刪除用戶之後,它只會崩潰。

有沒有什麼辦法可以指定這種關聯關係?謝謝!

回答

9

我想在實現這種行爲時使用mixin。我的模型定義如下:您可以通過deleteMethod你是否要到DELETE請求發送到您的API指定

App.DeletesDependentRelationships = Ember.Mixin.create({ 

    // an array of relationship names to delete 
    dependentRelationships: null, 

    // set to 'delete' or 'unload' depending on whether or not you want 
    // to actually send the deletions to the server 
    deleteMethod: 'unload', 

    deleteRecord: function() { 
     var transaction = this.get('store').transaction(); 
     transaction.add(this); 
     this.deleteDependentRelationships(transaction); 
     this._super(); 
    }, 

    deleteDependentRelationships: function(transaction) { 
     var self = this; 
     var klass = Ember.get(this.constructor.toString()); 
     var fields = Ember.get(klass, 'fields'); 

     this.get('dependentRelationships').forEach(function(name) { 
      var relationshipType = fields.get(name); 
      switch(relationshipType) { 
       case 'belongsTo': return self.deleteBelongsToRelationship(name, transaction); 
       case 'hasMany': return self.deleteHasManyRelationship(name, transaction); 
      } 
     }); 
    }, 

    deleteBelongsToRelationship: function(name, transaction) { 
     var record = this.get(name); 
     if (record) this.deleteOrUnloadRecord(record, transaction); 
    }, 

    deleteHasManyRelationship: function(key, transaction) { 
     var self = this; 

     // deleting from a RecordArray doesn't play well with forEach, 
     // so convert to a normal array first 
     this.get(key).toArray().forEach(function(record) { 
      self.deleteOrUnloadRecord(record, transaction); 
     }); 
    }, 

    deleteOrUnloadRecord: function(record, transaction) { 
     var deleteMethod = this.get('deleteMethod'); 
     if (deleteMethod === 'delete') { 
      transaction.add(record); 
      record.deleteRecord(); 
     } 
     else if (deleteMethod === 'unload') { 
      var store = this.get('store'); 
      store.unloadRecord(record); 
     } 
    } 
}); 

注:

App.Post = DS.Model.extend(App.DeletesDependentRelationships, { 
    dependentRelationships: ['comments'], 

    comments: DS.hasMany('App.Comment'), 
    author: DS.belongsTo('App.User') 
}); 

App.User = DS.Model.extend(); 

App.Comment = DS.Model.extend({ 
    post: DS.belongsTo('App.Post') 
}); 

的混入本身。如果您的後端配置爲自動刪除相關記錄,那麼您將需要使用默認設置。

這是一個jsfiddle,它顯示了它的行動。

+0

嘿,這看起來非常好!儘管我認爲'ember-data'應該支持核心內容。感謝這樣詳細的解釋,老兄! – josepjaume 2013-03-03 11:00:19

+0

我同意。 Ember Data缺少一些關鍵功能,但它仍然非常年輕,而且速度非常快。 – ahmacleod 2013-03-03 17:40:23

+1

Ember數據不再支持事務,所以上面的代碼需要修改才能使用最近的版本。 – ahmacleod 2013-09-11 19:20:49

3

快速和骯髒的方法是將以下內容添加到您的用戶模型

destroyRecord: -> 
    @get('comments').invoke('unloadRecord') 
    @_super() 
0

我適應@ahmacleod的答案與ember-cli 2.13.1ember-data 2.13.0工作。我有一個關於嵌套關係的問題,並且從數據庫中刪除一個實體後,它的id被重用了。這導致與餘燼數據模型中的殘餘物發生衝突。

import Ember from 'ember'; 

export default Ember.Mixin.create({ 
    dependentRelationships: null, 

    destroyRecord: function() { 
     this.deleteDependentRelationships(); 

     return this._super() 
     .then(function (model) { 
      model.unloadRecord(); 

      return model; 
     }); 
    }, 

    unloadRecord: function() { 
     this.deleteDependentRelationships(); 

     this._super(); 
    }, 

    deleteDependentRelationships: function() { 
     var self = this; 
     var fields = Ember.get(this.constructor, 'fields'); 

     this.get('dependentRelationships').forEach(function(name) { 
      self.deleteRelationship(name); 
     }); 
    }, 

    deleteRelationship (name) { 
     var self = this; 
     self.get(name).then(function (records) { 
      if (!records) { 
       return; 
      } 

      var reset = []; 
      if (!Ember.isArray(records)) { 
       records = [records]; 
       reset = null; 
      } 

      records.forEach(function(record) { 
       if (record) { 
        record.unloadRecord(); 
       } 
      }); 

      self.set(name, reset); 
     }); 
    }, 
}); 

最後,我必須的關係設定爲[](的hasMany)或null(屬於關聯)。否則我會碰到以下錯誤消息:

Assertion Failed: You cannot update the id index of an InternalModel once set. Attempted to update <id>.

也許這是對別人有幫助的。