将ManyToMany记录保存到rails后端

问题描述:

我在使用ember-data将相关记录保存到Rails后端时遇到问题。将ManyToMany记录保存到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数组?还是我错过了别的?

感谢,

马丁

要持续一个多服务器上的许多关系,我在黑客串行的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' 

有了这个地方,当时我犯了Product的JSON将包含一个键其中包含关联的类别ID数组。

UPDATE:

正确使用App.Serializer定义,你应该把它添加到应用程序的适配器:

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

而在你的应用程序中使用这个适配器,你必须将其设置在商店:

App.Store = DS.Store.extend 
    adapter: 'App.Adapter' 
+0

我已经添加了您的序列化代码来存储。RB及以下我的车型之一: 'FP.Adapter.map FP.observation, 学生: 连载: 'ids'' 然而,当我犯这样的: 'obs.get(' 学生).pushObjects(选择) obs.get('transaction')。commit()' 我没有看到任何对您的序列化程序代码的调用?应该在提交时调用它,对吗? – 2013-04-29 00:40:32

+0

是的,如果记录很脏,应该在提交时调用它,是否正确解决了您的请求?如果没有,您可能必须手动将记录标记为脏,因为修改*多对多关系不会将该记录标记为脏。 – 2013-05-02 08:14:18

+0

请求被触发,我可以在网络选项卡中看到它。在发送到服务器的json中,观察的学生成员是一个空阵列。当我深入了解余烬数据时,我可以通过观察模型的“关系”看到它。这只包含'belongsTo'关系,并没有'hasMany'关系。我想这就是为什么'addHasMany'没有被调用。所以它找到了房间和教育者的数据,并将这些数据添加到json中,但不是学生数据。 – 2013-05-02 13:52:03