I'm new to jsonapi and how the structure works and trying to get a relationship to load properly. I'm expecting ember-data to follow provided url's in the relationship.links of my objects to fetch the required information but I'm getting unexpected results.
I have Users, Territories, and a User/Territory relationship defined like this:
// User Model
const UserModel = DS.Model.extend({
username: DS.attr('string'),
territories: DS.hasMany('user-territories')
}
// Territory Model
const TerritoryModel = DS.Model.extend({
name: DS.attr('string')
}
// User-Territory Model
const UserTerritoryModel = DS.Model.extend({
notes: DS.attr('string'),
startDate: DS.attr('date'),
user: DS.belongsTo('user'),
territory: DS.belongsTo('territory')
}
I then have mock data (using http-mock) that looks like this:
// api/users/
data: {
type: "users",
id: 1,
attributes: {
username: "thisIsMyUsername"
}
},
relationships: {
territories: {
links: {
self: "http://localhost:4200/api/users/1/territories"
}
}
}
// api/users/1/territories
data: {
type: "user-territories",
id: 1,
attributes: {
notes: "This is a note",
startDate: "2017-01-01"
}
},
relationships: {
user: {
link: {
self: "http://localhost:4200/api/users/1"
}
},
territory: {
link: {
self: "http://localhost:4200/api/territories/1"
}
}
}
// api/territories/1
data: {
type: "territories",
id: 1,
attributes: {
name: "Territory #1"
}
}
In my User route, I want to request the UserModel and have access to the UserTerritory Relationship data and the Territory itself. The api calls are not what I expect though:
this.get('store').findRecord('user', 1, { include: "territories" });
EXPECTED:
ACTUAL:
If I call the user-territories model I get this:
EXPECTED:
ACTUAL:
If you use included
, ember-data basically thinks you want to tell the server to side-load data. If you return a links
, just resolve the relationship. However the relationships
have to be inside the data
. Also the self
link is for the relationship itself, to return the data use related
.
So first you do something like user = store.findRecord('user', '1')
, this will fetch to api/users/
. Then you should return something like this:
// api/users/
{
data: {
type: "users",
id: 1,
attributes: {
username: "thisIsMyUsername"
}
relationships: {
territories: {
links: {
related: "http://localhost:4200/api/users/1/territories"
}
}
}
}
}
Next you do user.get('territories')
. This will return a promise, and fetch http://localhost:4200/api/users/1/territories
, or whatever was inside that related link. However know, what ember-data
will expect you to return user-territories
here, because thats what you specified with territories: DS.hasMany('user-territories')
. You should know what you directly can model an many-to-many relationship in ember-data
without a third table.