1

我在使用 ember-data 将关联记录保存到 Rails 后端时遇到问题。

楷模:

FP.Student = DS.Model.extend

  firstName:    DS.attr('string')
  lastName:     DS.attr('string')
  imageUrl:     DS.attr('string')

  room:         DS.hasMany('FP.Room')
  parents:      DS.hasMany('FP.Parent')
  observations: DS.hasMany('FP.Observation')


FP.Observation = DS.Model.extend

  name:         DS.attr('string')
  description:  DS.attr('string')
  observedAt:   DS.attr('string')

  room:         DS.belongsTo('FP.Room')
  educator:     DS.belongsTo('FP.Educator')
  students:     DS.hasMany('FP.Student', embedded: true)

我想将选择视图中的预先存在的学生列表添加到新的观察中。假设学生模型已经收集在controller.selectedStudents我做:

 saveObservation: ->
    console.log "ObservationsController saveObservation"
    obs = @get('newObservation') # new observation is created previously
    obs.set('observedAt', new Date)
    obs.set('room', @get('room'))
    obs.set('educator', @get('room.educators').objectAt(0))
    selected = @findSelectedStudents()
    obs.get('students').pushObjects(selected)
    obs.get('transaction').commit()

findSelectedStudents: ->
    @get('selectedStudents').map( (id) =>
      @get('students').find( (student) ->
        student.id is id
      )
    )

发送回服务器的结果 json 如下所示(来自服务器日志):

Started POST "/observations" for 127.0.0.1 at 2013-04-24 21:04:12 +1000
Processing by ObservationsController#create as JSON
  Parameters: {"observation"=>
{"name"=>"DDS", "description"=>"asdsad", "observed_at"=>"Wed Apr 24 2013 21:04:04 GMT+1000 (EST)", "room_id"=>203, "educator_id"=>535, 
"students"=>[{"id"=>605, "first_name"=>"Steven", "last_name"=>"Richards", "image"=>"https://www.filepicker.io/api/file/CTUCsDGwdEVaS"},
 {"id"=>607, "first_name"=>"Anna", "last_name"=>"Stone", "image"=>"https://www.filepicker.io/api/file/CTUCsDGwdEVaS"}]}}
 Completed 500 Internal Server Error in 5ms

很抱歉布局,但有 2 名学生,有完整的属性列表。服务器抛出的错误是ActiveRecord::AssociationTypeMismatch - Student(#70343949384800) expected, got ActiveSupport::HashWithIndifferentAccess(#70343953246680)

现在,我使用 ajax 回调将学生序列化为一个student_ids数组,其中仅包含学生 ID。服务器接受此调用并建立关联。但我更喜欢使用 ember-data,而不是像手动 ajax 解决方案那样遇到手动记录管理的麻烦。

我已经尝试在 Observation 上设置一个数组student_ids,但是没有任何东西被发送回服务器。

我认为如果关联被命名,当前调用可能会起作用student_attributes,但如果学生记录不脏,发送所有数据似乎是浪费时间。

那么,我是否应该尝试覆盖序列化程序以发回一组 student_ids?还是我错过了其他东西?

谢谢,

马丁

4

1 回答 1

1

为了在服务器上保持多对多关系,我正在破解序列化程序的方法以在映射hasMany中添加一个选项。serialized

这是序列化程序(CoffeeScript):

App.Serializer = DS.RESTSerializer.extend

  # redefine to make it possible to serialize a relationship by an array of ids
  # to enable it, a 'serialized' property should be set to 'ids' in the adapter mapping
  # the key in the hash will be the type of the object in the relation ship + _ids'
  # example : for an hasMany('App.Category'), the key will be category_ids
  addHasMany: (hash, record, key, relationship) ->
    type = record.constructor
    name = relationship.key

    serializedType = @serializedType type, name

    if serializedType is 'ids'
      key = @singularize(@keyForAttributeName(type, name)) + "_ids"
      manyArray = record.get name
      serializedIds = []
      manyArray.forEach (record) ->
        serializedIds.push record.get('id')
      hash[key] = serializedIds
    else
      return @_super hash, record, key, relationship

  # method to access the serialized option in adapter mapping
  serializedType: (type, name) ->
    @mappingOption type, name, 'serialized'

这是一个映射配置示例:

App.Adapter.map App.Product,
  categories:
    serialized: 'ids'

有了这个,当我提交一个Productjson 将包含一个category_ids包含相关类别 ID 数组的键。

更新:

要正确使用App.Serializer定义,您应该将其添加到应用程序的适配器中:

App.Adapter = DS.RESTAdapter.extend
  serializer: App.Serializer

要在您的应用程序中使用此适配器,您必须在 store 中设置它:

App.Store = DS.Store.extend
  adapter: 'App.Adapter'
于 2013-04-25T22:22:16.330 回答