Use ID of belongsTo relation without loading the whole record


#1

Hey!

I have the following problem:

I want to read the ID of an async belongsTo relation without loading the whole record from the server.

Background: We have a user model and a plan model. The plan model has a belongsTo relation to a user. Now a user can share his plans to other users. To determine if a plan is shared or not, we compare the user-id of the actual authenticated user and the user-id which is in the belongsTo relation of the plan. If I do the following in the plan route:

if(this.get('session.data.authenticated.auth.userId') !== this.get('model.user.id') {
    //...
    //...
}

The user is fetched but we don’t want that every user can fetch every others user details. The backend returns http 403 -> forbidden. Now I tried to get around this issue with some internal private members which seems very hackish to me. When I access the user.id of the plan with:

model.get('_internalModel._relationships.initializedRelationships.user.canonicalState.id')

I get the id without a server request. Is there a public API to do this or is my hackish way the only way to solve this issue?

Thanks a lot Bye


#2

This can be achieved using the ds-references feature:

var auth = this.get("session.data.authenticated.auth");
var id = auth.belongsTo("user").id();

Also see http://emberjs.com/blog/2016/01/12/ember-data-2-3-released.html#toc_code-ds-references-code and http://emberup.co/references-api-in-ember-2-4/.


#3

@pangratz Thank you for the hint, but it does not work. When I do this in the route I get the following exception:

Assertion Failed: The `belongsTo` method is not available on DS.Model, a DS.Snapshot was probably expected. Are you passing a DS.Model instead of a DS.Snapshot to your serializer?

I do the following in the route:

setupController: function (controller, model) {
    var creator = model.belongsTo('user').id();
}

My model looks as follows:

import Ember from 'ember';
import DS from 'ember-data';

export default DS.Model.extend({

    // Data
    name: DS.attr('string'),
    description: DS.attr('string'),
    // ...
    // ...
    // ...

    // Relationships
    user: DS.belongsTo('user', {async: true}),
    // ...
});

#4

You need to enable the ds-references feature via the EmberENV, see this: http://emberjs.com/blog/2016/01/12/ember-data-2-3-released.html#toc_upcoming-features


#5

@pangratz Thank you for the hint! I think I should read the blog posts in more depth :wink: Now it works. Although I can not use it in production since I don’t want to use a canary build in production. But nice to know that there will land a feature which solve the problem