问题
I'm having the following problem.
In my app I have a screen to make a new Site
. But when I save the new site via an action
on the controller, the languages
-property isn't sent with the POST
-request to the server.
The template for adding a new Site is this:
<form class="form-horizontal">
<div class="control-group">
<label class="control-label" for="name">Name</label>
<div class="controls">
{{view Ember.TextField valueBinding="name"}}
</div>
</div>
<div class="control-group">
<label class="control-label" for="languages">Languages</label>
<div class="controls">
{{view Ember.Select contentBinding="controllers.languages" selectionBinding="languages" optionValuePath="content.id" optionLabelPath="content.description" multiple="true"}}
</div>
</div>
<div class="form-actions">
<button {{ action "createSite" }} class="btn btn-primary">Save</button>
</div>
I defined my Store
like this:
App.Store = DS.Store.extend({
revision : 12,
adapter : DS.RESTAdapter.extend({
namespace : 'rest'
})
});
This is my controller:
App.SitesNewController = Em.ObjectController.extend({
needs: ['languages'],
name: null,
languages: null,
createSite : function() {
var self = this;
var name = this.get('name');
var languages = this.get('languages');
// Create the new Site model
var s = App.Site.createRecord({
name : name
});
$.each(languages,function(i,lang) {
s.get('languages').addObject(lang);
});
this.get('store').commit();
}
});
This is the Site
-model
App.Site = DS.Model.extend({
name : DS.attr('string'),
languages : DS.hasMany('App.Language')
});
Language
-model:
App.Language = DS.Model.extend({
description : DS.attr('string')
});
The POST
-request data sent to my server is this:
{
"site":{"name":"test"}
}
So I miss the language
-property. Actually I expect a language_ids
property with an array of id's.
When I edit my RESTAdapter
-configuration like this:
DS.RESTAdapter.map('App.Site', {
languages: { embedded: 'always' }
});
Now the POST
-request data is:
{
"site": {
"name":"test",
"languages":[{
"id":2,"description":"English"
},{
"id":3,"description":"Deutsch"
}]
}
}
The languages are know embedded in the request-data. This is no problem, at the backend I get the id
before I save it. But know it expects the language
-data to be embedded in the GET-responses also.
What is the way to send just the id
's in the POST-data? I want it to be something like this:
{
"site": {
"name":"test",
"languages":[2,3]
}
}
回答1:
This answer is largely derived from this other StackOverflow answer.
App.Store = DS.Store.extend({
revision : 12,
adapter : DS.RESTAdapter.extend({
namespace : 'rest',
serializer: DS.RESTSerializer.extend({
addHasMany: function (hash, record, key, relationship) {
var type = record.constructor,
name = relationship.key,
serializedHasMany = [],
manyArray, embeddedType;
embeddedType = this.embeddedType(type, name);
if (embeddedType !== 'always') { return; }
manyArray = record.get(name);
manyArray.forEach(function (record) {
serializedHasMany.push(record.get('id'));
}, this);
hash[this.singularize(key) + '_ids'] = serializedHasMany;
}
})
})
});
For reference, you might review the JSONSerializer
, which the RESTSerializer
mostly inherits from. The code for what addHasMany
does can be found here.
Note that, for the above snippet, the only lines that really differ are the last several. Rather than serializing embedded records, ids are pushed to the hash under the singularized key (I would have used RESTSerializer#keyForHasMany
if it didn't have its own check for embedded types.
来源:https://stackoverflow.com/questions/15683273/save-foreign-key-to-other-model-with-hasmany-relation