Leandro Alves
Leandro Alves

Reputation: 23

Reflexive relation with nested data

I'm sorry if this is a basic question, but since I'm quite new to ember, I'd like to know if there is any best practice for a case like this. For example, I have the follow endpoints that returns the payloads below:

https://api.example.com/v1/user

[
    {
        "user": "user1",
        "firstName": "Foo1",
        "lastName": "Bar1",
        "url": "https://api.example.com/v1/user/user1"
    },
    {
        "user": "user2",
        "firstName": "Foo2",
        "lastName": "Bar2",
        "url": "https://api.example.com/v1/user/user2"
    }
]

And each of the "url" endpoint returns something like this:

https://api.example.com/v1/user/user1

{
    "user": "user1",
    "firstName": "Foo1",
    "lastName": "Bar1",
    "age": 21,
    "address": "User1 Address"
    ... more info ...
}

We see that some properties in "/user" are repeated in "/user/user1".

What would be the best practice to create the "user" model?

Should I have two models? Like for example a "users" model for the "/user" and a "user" model for "/user/user1"?

Could somehow have just one model "user" that would fit both endpoints?

Thanks in advance!

Upvotes: 2

Views: 109

Answers (1)

harkl
harkl

Reputation: 901

This is almost the use case described in the one-to-one docs where you're defining the user data with one model and linking another model with a belongsTo attribute:

// app/models/user.js
import DS from 'ember-data';

export default DS.Model.extend({
  user: DS.attr('string'),
  firstName: DS.attr('string'),
  lastName: DS.attr('string'),
  url: DS.attr('string'),

  profile: DS.belongsTo('profile')
});

then setup a profile model with any extra values you're wanting to add and define the belongsTo attribute also:

// app/models/profile.js
import DS from 'ember-data';

export default DS.Model.extend({
  age: DS.attr('string'),
  address: DS.attr('string'),

  user: DS.belongsTo('user')
});

In your routes file you'll want to setup the user id to define your URL structure like so:

//app/router.js
Router.map(function() {
  this.route('users');
  this.route('user', { path: '/user/:user_id' });
});

Then finally you'll need to load the data retrieving the related records and loading them in via your route file.

// app/routes/user.js
import Route from '@ember/routing/route';

export default Route.extend({
  model(params) {
   return this.store.findRecord('user', params.user_id, {include: 'profile'});
  }
});

It's worth pointing out that you may also need a serializer to massage the data into the format you're wanting.

Upvotes: 1

Related Questions