Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ember Data 1.0.0: what is expected format for belongsTo relationship

I have the following models:

App.Publication = DS.Model.extend({
  title: DS.attr('string'),
  bodytext: DS.attr('string'),
  author: DS.belongsTo('author')
});

App.Author = DS.Model.extend({
  name: DS.attr('string')
});

And the folowing json data:

{
  "publications": [
  {
    id: '1',
    title: 'first title',
    bodytext: 'first body',
    author_id: 100
  },
  {
    id: '2',
    title: 'second title',
    bodytext: 'second post',
    author_id: 200
  }
];
}

In Ember Data RC12 this worked (you could specify author_id OR author in the json and the publication would always have the correct author linked).

In Ember Data 1.0.0 this no longer works; author is always null.

In some documents I found that - since I am using "author_id" in the json data (and not simply author) - I need to specify the key in the model; thus:

 author: DS.belongsTo('author', { key: 'author_id' })

This however does not work; the author in the publication remains null.

The only solution I see for now is to implement a custom serializer and override the author_id to author (via normailzeId); I cannot change my backend data structure ... thus:

App.MySerializer = DS.RESTSerializer.extend({
  //Custom serializer used for all models
  normalizeId: function (hash) {
    hash.author = hash.author_id;
    delete hash.author_id;
    return hash;
  }
});

Is the above the correct way ?

like image 721
cyclomarc Avatar asked Feb 16 '23 08:02

cyclomarc


2 Answers

Ember Data 1.0 no longer does any payload normalization by default. The key configuration for DS.belongsTo has been removed as well so you will have to implement a custom serializer.

normalizeId is an internal serializer function used for converting primary keys to always be available at id. You shouldn't override this.

Instead, you can override the keyForRelationship method which is provided for this purpose.

You could use something like the following:

App.ApplicationSerializer = DS.RESTSerializer.extend({
  keyForRelationship: function(rel, kind) {
    if (kind === 'belongsTo') {
      var underscored = rel.underscore();
      return underscored + "_id";
    } else {
      var singular = rel.singularize();
      var underscored = singular.underscore();
      return underscored + "_ids";
    }
  }
});

Note: I've also renamed the serializer to App.ApplicationSerializer so that it will be used as the default serializer for your application.

Finally, if you haven't already found it, please take a look at the transition notes here: https://github.com/emberjs/data/blob/master/TRANSITION.md

If you read through the transition document shortly after the initial 1.0.0.beta.1 release I would recommend taking a look again as there have been a number of additions, particularly regarding serialization.

like image 125
Justin Giancola Avatar answered May 16 '23 08:05

Justin Giancola


From the Ember 1.0.0 Transition Guide:

Underscored Keys, _id and _ids

In 0.13, the REST Adapter automatically camelized incoming keys for you. It also expected belongsTo relationships to be listed under name_id and hasMany relationships to be listed under name_ids.

If your application returns json with underscored attributes and _id or _ids for relation, you can extend ActiveModelSerializer and all will work out of the box.

App.ApplicationSerializer = DS.ActiveModelSerializer.extend({});

Note: DS.ActiveModelSerializer is not to be confused with the ActiveModelSerializer gem that is part of Rails API project. A conventional Rails API project with produce underscored output and the DS.ActiveModelSerializer will perform the expected normalization behavior such as camelizing property keys in your JSON.

like image 40
rxgx Avatar answered May 16 '23 06:05

rxgx