0

I've got a model called "Membership" that has a string attribute "inviteToken" which I would like to use as my primary key.

I've created the following serializer, but cannot get it to pick up the primary key from the JSON.

app/serializers/membership.js:

import DS from 'ember-data';

export default DS.JSONAPISerializer.extend({
  primaryKey: 'invite-token' // also tried 'inviteToken'
});

The specific error I'm getting is:

Error while processing route: invitations.show Assertion Failed: You must include an 'id' for membership in an object passed to 'push'
Error: Assertion Failed: You must include an 'id' for membership in an object passed to 'push'

Which happens when I try to get a record by its ID in the route:

import Ember from 'ember';

export default Ember.Route.extend({
  model(params) {
    return this.store.find('membership', params.token);
  }
});

API Response:

{
  "jsonapi":{
    "version":"1.0"
  },
  "data":{
    "type":"membership",
    "id":"30",
    "attributes":{
      "invite-token":"5bGo7IhZh93E4SB07VWauw"
    }
  }
}

The strange thing is that if I use "type" as the primary key, I see "membership" as the id in the ember inspector. It's as if ember data doesn't know how to use something from the "attributes". I'm using ember data 2.4.0.

Update

I can hack this to work in my serializer by doing this:

import DS from 'ember-data';

export default DS.JSONAPISerializer.extend({
  normalize: function(type, hash) {
    const json =  this._super(type, hash);
    json.data.id = json.data.attributes.inviteToken;

    return json;
  }
});
2
  • When do you get these errors? What concrete code which has to do with store causes that? Commented Mar 1, 2016 at 20:43
  • @DanielKmak I added the route code and a serializer that does what I need it to do. Commented Mar 1, 2016 at 21:38

1 Answer 1

3

The serializer expects the value of primaryKey to refer to a top level element in the json. This is why "type" and "id" works. It currently does not support nested properties (for example primaryKey: "attributes.invite-token")

However there are two good workarounds:

The first is overriding the extractId method. The default implementation is quite simple. In your case you could do something like:

extractId(modelClass, resourceHash) {
    var id = resourceHash['attributes']['invite-key';
    return coerceId(id);
  },

The second way is the method you discovered, a more brute force approach, and that is to assign the id manually in the normalize function.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.