Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 722
Charlie Avatar asked Feb 28 '13 14:02

Charlie


People also ask

How do you save Ember?

Records in Ember Data are persisted on a per-instance basis. Call save() on any instance of Model and it will make a network request. Ember Data takes care of tracking the state of each record for you. This allows Ember Data to treat newly created records differently from existing records when saving.

What are polymorphic models in ember?

Polymorphism. Polymorphism is a powerful concept which allows a developer to abstract common functionality into a base class. Consider the following example: a user with multiple payment methods. They could have a linked PayPal account, and a couple credit cards on file.

What is an ember model?

In Ember Data, models are objects that represent the underlying data that your application presents to the user. Note that Ember Data models are a different concept than the model method on Routes, although they share the same name.


1 Answers

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 ...
      }
    })
  })
});
like image 123
ahmacleod Avatar answered Oct 02 '22 23:10

ahmacleod