将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'
我已经添加了您的序列化代码来存储。RB及以下我的车型之一: 'FP.Adapter.map FP.observation, 学生: 连载: 'ids'' 然而,当我犯这样的: 'obs.get(' 学生).pushObjects(选择) obs.get('transaction')。commit()' 我没有看到任何对您的序列化程序代码的调用?应该在提交时调用它,对吗? – 2013-04-29 00:40:32
是的,如果记录很脏,应该在提交时调用它,是否正确解决了您的请求?如果没有,您可能必须手动将记录标记为脏,因为修改*多对多关系不会将该记录标记为脏。 – 2013-05-02 08:14:18
请求被触发,我可以在网络选项卡中看到它。在发送到服务器的json中,观察的学生成员是一个空阵列。当我深入了解余烬数据时,我可以通过观察模型的“关系”看到它。这只包含'belongsTo'关系,并没有'hasMany'关系。我想这就是为什么'addHasMany'没有被调用。所以它找到了房间和教育者的数据,并将这些数据添加到json中,但不是学生数据。 – 2013-05-02 13:52:03