我们正在为这个项目使用JSONAPI,但是由于[原因]我们无法在API中处理它推荐的关系结构,所以我们正在服务并期望它们作为嵌套对象,而是采用以下格式:
{
"data":{
"type":"video",
"id":"55532284a1f9f909b0d11d73",
"attributes":{
"title":"Test",
"transcriptions":{
"type": "embedded",
"data":[
{
"type":"transcription",
"id":"203dee25-4431-42d1-a0ba-b26ea6938e75",
"attributes":{
"transcriptText":"Some transcription text here. And another sentence after it.",
"cuepoints":{
"type":"embedded",
"data":[
{
"type":"cuepoint",
"id":"bb6b0434-bdc4-43e4-8010-66bdef5c432a",
"attributes":{
"text":"Some transcription text here."
}
},
{
"type":"cuepoint",
"id":"b663ee00-0ebc-4cf4-96fc-04d904bc1baf",
"attributes":{
"text":"And another sentence after it."
}
}
]
}
}
}
]
}
}
}
}
我有以下模型结构:
// models/video
export default DS.Model.extend({
transcriptions: DS.hasMany('transcription')
)};
// models/transcription
export default DS.Model.extend({
video: DS.belongsTo('video'),
cuepoints: DS.hasMany('cuepoint')
});
// models/cuepoint
export default DS.Model.extend({
transcription: DS.belongsTo('transcription')
);
现在,我们要做的是保存video
条记录,并让它序列化它包含的transcriptions
和cuepoints
。我有以下序列化程序,它可以很好地将transcription
嵌入到video
中。一个级别,但我需要它然后将cuepoints
嵌入其中。
export default DS.JSONAPISerializer.extend({
serializeHasMany: function(record, json, relationship) {
var hasManyRecords, key;
key = relationship.key;
hasManyRecords = Ember.get(record, key);
if (hasManyRecords) {
json.attributes[key] = {};
hasManyRecords.forEach(function(item) {
json.attributes[key].data = json.attributes[key].data || [];
json.attributes[key].data.push({
attributes: item._attributes,
id: item.get('id'),
type: item.get('type')
});
});
} else {
this._super(record, json, relationship);
}
}
});
检查record
方法中的json
,relationship
和serializeHasMany
属性,我看不到有关嵌套关系的任何信息,所以甚至不确定我是不是使用正确的方法。
我有什么想法吗?
答案 0 :(得分:0)
您必须为每个模型添加序列化程序,并根据需要在右侧序列化程序中调整有效负载。上面的序列化程序会生成您在说明中提供的确切有效负载。
应用/串行化器/ cuepoint.js 强>
import DS from 'ember-data';
export default DS.JSONAPISerializer.extend({
payloadKeyFromModelName (modelName) {
return modelName;
},
serialize (record, options) {
return this._super(record, options).data;
},
serializeBelongsTo () {}
});
应用/串行化器/ transcription.js 强>
import DS from 'ember-data';
export default DS.JSONAPISerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
cuepoints: {
serialize: 'records',
deserialize: 'records'
}
},
keyForAttribute (key, method) {
return key;
},
payloadKeyFromModelName (modelName) {
return modelName;
},
serialize (record, options) {
let json = this._super(record, options);
json.data.attributes.cuepoints = {
type: 'embedded',
data: json.data.cuepoints
}
delete json.data.cuepoints;
return json.data;
},
serializeBelongsTo () {}
});
应用/串行化器/了Video.js 强>
import DS from 'ember-data';
export default DS.JSONAPISerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
transcriptions: {
serialize: 'records',
deserialize: 'records'
}
},
payloadKeyFromModelName (modelName) {
return modelName;
},
serialize (record, options) {
let json = this._super(record, options);
json.data.attributes.transcriptions = {
type: 'embedded',
data: json.data.transcriptions
}
delete json.data.transcriptions;
return json;
},
serializeBelongsTo () {}
});
答案 1 :(得分:0)
我想我已经弄明白了。有一些我不知道存在的用于循环关系的方法,我需要编写一个自定义serialize
方法,而不是仅覆盖默认的serializeHasMany
方法。
serialize(record) {
// Set up the main data structure for the record to be serialized
var JSON = {
data: {
id: record.id,
type: record.modelName,
attributes: {}
}
};
// Find relationships in the record and serialize them into the JSON.data.attributes object
JSON.data.attributes = this.serializeRelationships(JSON.data.attributes, record);
// Loop through the record's attributes and insert them into the JSON.data.attributes object
record.eachAttribute((attr) => {
JSON.data.attributes[attr] = record.attr(attr);
});
// Return the fully serialized JSON data
return JSON;
},
// Take a parent JSON object and an individual record, loops through any relationships in the record, and creates a JSONAPI resource object
serializeRelationships(JSON, record) {
record.eachRelationship((key, relationship) => {
if (relationship.kind === 'hasMany') {
// Set up the relationship data structure
JSON[relationship.key] = {
data: []
};
// Gran any relationships in the record
var embeddedRecords = record.hasMany(relationship.key);
// Loop through the relationship's records and build a resource object
if (embeddedRecords) {
embeddedRecords.forEach((embeddedRecord) => {
var obj = {
id: embeddedRecord.id,
type: embeddedRecord.modelName,
attributes: {}
}
// Recursively check for relationships in the record
obj.attributes = this.serializeRelationships(obj.attributes, embeddedRecord);
// Loop through the standard attributes and populate the record.data.attributes object
embeddedRecord.eachAttribute((attr) => {
obj.attributes[attr] = embeddedRecord.attr(attr);
});
JSON[relationship.key].data.push(obj);
});
}
}
});
return JSON;
}