Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ember data alias model / Map JSON response

My server returns a JSON response like this:

{
  artists: [{
    id: "1",
    first_name: "Foo",
    last_name: "Bar"
}],
  studios: [{
    id: 1,
    name: "Test",
    // ...
    artist_ids: ["1"]
  }]
}

'artist' is in fact a User model but with a different name. How can I map artist to the User model? Maybe a bad explanation but if I rename the JSON response serverside to 'users' instead of 'artist' and use the models below everything works like I want. I simply want to use the name 'artist' instead of 'user', both server side and client side. Hope you guys understand what i mean.

App.Studio = DS.Model.extend
  name:  DS.attr 'string'
  // ..
  users: DS.hasMany 'App.User'

App.User = DS.Model.extend
  firstName:  DS.attr 'string'
  lastName:  DS.attr 'string'
  studio: DS.belongsTo 'App.Studio'

I guess that the simplest thing to do would be something like artists: DS.hasMany 'App.User' but obviously this does not work.

like image 663
Timmie Sarjanen Avatar asked Jan 13 '23 06:01

Timmie Sarjanen


1 Answers

First, I recommend using the latest Ember / EmberData, so relationships are defined like this:

App.Studio = DS.Model.extend({
  name:  DS.attr('string'),
  // ..
  users: DS.hasMany('user')
});

App.User = DS.Model.extend({
  firstName:  DS.attr('string'),
  lastName:  DS.attr('string'),
  studio: DS.belongsTo('studio')
});

Next, I recommend using the ActiveModelAdapter if you are getting underscores in your response JSON:

App.ApplicationAdapter = DS.ActiveModelAdapter;

Finally, overriding typeForRoot and keyForRelationship in a custom serializer should fix your issue:

App.ApplicationSerializer = DS.ActiveModelSerializer.extend({
  typeForRoot: function(root) {
    if (root == 'artist' || root == 'artists') { root = 'user'; }
    return this._super(root);
  },

  keyForRelationship: function(key, kind) {
    if (key == 'users') { key = 'artists'; }
    return this._super(key, kind);
  }
});

Example JSBin

One last thing: you can even get rid of the custom keyForRelationship if you name the relationship artists in Studio:

App.Studio = DS.Model.extend({
  name:  DS.attr('string'),
  // ..
  artists: DS.hasMany('user')
});
like image 169
gerry3 Avatar answered Feb 08 '23 18:02

gerry3