Подтвердить что ты не робот

Полиморфные ассоциации Ember-данных

Кто-нибудь придумал ответ для полиморфных ассоциаций и ember-данных?

Нам нужен какой-то способ запросить тип на другом конце отношения из того, что я могу сказать.

Кто-нибудь думает об этом?

4b9b3361

Ответ 1

С последней сборкой данных ember-data теперь вы можете использовать полиморфные ассоциации:

Вам нужно настроить свои модели, чтобы сделать их полиморфными:

/* polymorphic hasMany */
App.User = DS.Model.extend({
 messages: DS.hasMany(App.Message, {polymorphic: true})
});

App.Message = DS.Model.extend({
  created_at: DS.attr('date'),
  user: DS.belongsTo(App.User)
});

App.Post = App.Message.extend({
  title: DS.attr('string')
});

/* polymorphic belongsTo */
App.Comment = App.Message.extend({
  body: DS.attr('string'),
  message: DS.belongsTo(App.Message, {polymorphic: true})
});

Вам также нужно настроить свойства alias на RESTAdapter

DS.RESTAdapter.configure('App.Post' {
  alias: 'post'
});
DS.RESTAdapter.configure('App.Comment' {
  alias: 'comment'
});

Результат, ожидаемый от вашего сервера, должен выглядеть следующим образом:

{
    user: {
        id: 3,
        // For a polymorphic hasMany
        messages: [
            {id: 1, type: "post"},
            {id: 1, type: "comment"}
        ]
    },

    comment: {
        id: 1,
        // For a polymorphic belongsTo
        message_id: 1,
        message_type: "post"
    }
}

Дополнительная информация в этот поток github

Ответ 2

Итак, у меня есть что-то. Он не закончен, или полностью чист, но он работает. В принципе, я использую mixin, чтобы полностью обходить ассоциации Ember. Я уверен, что это можно было перевернуть в адаптер или в хранилище, но пока это работает.

Полиморфные модели проходят через JSON с элементами itemId и itemType:

App.Follow = DS.Model.extend
  user: DS.belongsTo('App.User')
  itemId: DS.attr("number")
  itemType: DS.attr("string")

Я добавляю mixin к связанным с ним моделям:

App.Hashtag = DS.Model.extend App.Polymorphicable,
  follows:(-> 
  name: DS.attr("string")
    @polymorphicFilter(App.Follow, "Hashtag")
  ).property('changeCount')  #changeCount gives us something to bind to

  followers: (->
    @get('follows').map((item)->item.get('user'))
  ).property('follows')

Mixin реализует три метода: один, который обновляет changeCount, который возвращает тип модели и метод polymorphicFilter, который фильтрует модель по типу itemty и id:

App.Polymorphicable = Ember.Mixin.create
  changeCount: 1 

  polymorphicFilter: (model, itemType)->
    App.store.filter model, 
      (data) =>
        if data.get('itemId')
          @get('id') is data.get('itemId').toString() and data.get('itemType') is itemType 

  itemType:()->
    @constructor.toString().split('.')[1]

  updatePolymorphicRelationships:()->
    @incrementProperty('changeCount')

Уровень контроллера защищен от всей этой болтовни, за исключением необходимости называть updatePolymorphicRelationship, чтобы убедиться, что привязки загорелись:

App.HashtagController = Ember.ObjectController.extend
  follow:()->
    App.Follow.createRecord({
      user: @get('currentUserController.content')
      itemId: @get('id')
      itemType: @get('content').itemType()
    })
    #this provides a way to bind and update. Could be refactored into a didSave()
    #callback on the polymorphic model.
    @get('content').updatePolymorphicRelationships()
    App.store.commit()

Что я до сих пор. Я пытаюсь удержать вещи на уровне модели, так как он удаляется только одним шагом из слоя адаптера. Если это похоже на то, что Ember Data в будущем не будет смотреть на полиморфику, тогда было бы разумно вывести все это на более высокий уровень, но на данный момент это работает и оставляет мои контроллеры (относительно) чистыми.