Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
311 views
in Technique[技术] by (71.8m points)

javascript - Ember data saving a relationship

I'm having difficult saving a one-to-many relationship in ember data. I have a relationship like this:

App.ParameterSet = DS.Model
    name: DS.attr("string")
    regions: DS.hasMany("App.Region")

App.Region = DS.Model
    name: DS.attr("string")

If I were to do something like this:

parameterSet = App.ParameterSet.find(5)
@transaction = @get("store").transaction()
@transaction.add(parameterSet)
region1 = App.Region.find(10)
region2 = App.Region.find(11)
parameterSet.set("name", "foo")
parameterSet.get("regions").pushObject(region)
@transaction.commit()

Then I would like to see a PUT request with payload like this:

api/ParameterSets/5

{parameterSet: {name: "foo", regionIds:[10, 11]}}

but instead I get this:

{parameterSet: {name: "foo"}}

I don't care about the relationship back from child to parent but if I add parameterSet: DS.belongsTo("App.ParameterSet") to the App.Region model then I get 2 PUT requests to the regions url for the two new relationships which is not really what I want.

I guess this is a many-to-many relationship really which I'm not sure is yet supported but any ideas on how to achieve what I've described? Thanks

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The serialization of hasMany relationships is handled by the addHasMany() method of json_serializer.js.

The following note is included in the source code:

The default REST semantics are to only add a has-many relationship if it is embedded. If the relationship was initially loaded by ID, we assume that that was done as a performance optimization, and that changes to the has-many should be saved as foreign key changes on the child's belongs-to relationship.

To achieve what you want, one option is to indicate that the relationship should be embedded in your adapter.

App.Store = DS.Store.extend({
  adapter: DS.RESTAdapter.extend({
    serializer: DS.RESTSerializer.extend({
      init: function() {
        this._super();
        this.map('App.ParameterSet', {
          regions: { embedded: 'always' }
        });
      }
    })
  })
});

Of course now your back-end will need to actually embed the associated regions' JSON within the parameter set's JSON. If you want to keep things as they are, you can simply override addHasMany() with custom serialization.

App.Store = DS.Store.extend({
  adapter: DS.RESTAdapter.extend({
    serializer: DS.RESTSerializer.extend({
      addHasMany: function(hash, record, key, relationship) {
        // custom ...
      }
    })
  })
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...