存储多态hasMany:一个余烬bug?

时间:2014-04-10 00:50:15

标签: javascript ember.js ember-data

如果我有以下型号:

App.Foo = DS.Model.extend({
  name: DS.attr('string')
});

App.Bar = App.Foo.extend({
  foos: DS.hasMany('foo',{
    polymorphic: true, async: true
  })
});

当我尝试保存“foos”时出错。还有其他我应该做的事吗?

App.IndexRoute = Ember.Route.extend({
  model: function() {
    var store = this.get('store');
    f1 = store.createRecord(
      'foo', { name: 'foo'});
    b2 = store.createRecord(
      'bar', { name: 'bar' } );
    return b2;
  },
  afterModel: function( b2 ) {
    p = b2.get('foos').then(function(foos) {
      foos.addRecord(f1);
      return foos.save().then(function(){ 
        return b2.save().then(function(){ 
          console.log('ok');
          return b2;
        });
      });
    });
    return p;
  }
});

错误是:“无法设置未定义的属性'store' - 似乎在内部,传递了一个id数组(而不是id和类型) - 然后modelFor失败。

谢谢!

修改:jsbin:http://emberjs.jsbin.com/EnOqUxe/20/edit

1 个答案:

答案 0 :(得分:0)

实际上它是一个bug ...与belongsTo的类似问题有关。 See discussion

这是我在coffeescript中的修复。 NB我从缓存中获取有关相关对象的私有数据,而不是等待承诺:我认为强制服务器发送相关对象以序列化给定对象并不是一个好主意。但是,应该有"官方"接口到相关对象的id和类型,封装了这段代码获取它们的hackish方式。

DS.JSONSerializer.reopen

  # returns object related by given relationship.
  # 
  # The form can be related object, as-yet not unserialized
  # reference, or null
  getRelated: ( record, key ) ->
    related = Ember.get record, key
    if related?.then?
      if !related.isFulfilled
        related = record.get( 'data' )[ key ]
      else
        related = related.content
    return related

  getRelatedId: ( related ) ->
    return related.id || related

  serializeBelongsTo: (record, json, relationship) ->

    key = relationship.key
    belongsTo = @getRelated record, key
    key = @keyForRelationship?( key ) || key

    if Ember.isNone(belongsTo)
      json[key] = belongsTo
    else
      json[key] = @getRelatedId belongsTo

    if relationship.options.polymorphic
      this.serializePolymorphicType(record, json, relationship)

  serializeHasMany: (record, json, relationship) ->
    key = relationship.key
    relationshipType = DS.RelationshipChange.determineRelationshipType(
      record.constructor, relationship)

    # for opposite of one-to-many, default is to only save opposite
    if relationshipType is "manyToNone" or relationshipType is "manyToMany"
      related = @getRelated(record, key)
      if Ember.isNone(related)
        json[key]= related
      else
        json[key] = related.mapBy("id")
        if relationship.options.polymorphic
          this.serializePolymorphicType(record, json, relationship)
    return

  serializePolymorphicType: (record, json, relationship) ->
    key = relationship.key
    kind = relationship.kind
    convert = (related)=>
      if !Ember.isNone(related)
        typeKey = related.constructor.typeKey || related.type
        return {
          id: @getRelatedId related
          type: typeKey
        }
      else
        related
    related = @getRelated( record, key )
    key = @keyForAttribute?(key) || key
    if kind == 'belongsTo'      
      json[key] = convert( related )
    else if (kind == 'hasMany' )
      json[key] = related.content.map (rel)->
        convert(rel)
    else
      Ember.assert(
        'Relationship kind {#relationship.kind} not supported yet', false )