Series: Introduction to Ember Data 2.0

Serializers-Extracting Relationships

Published on May 06, 2016

The relationships hash in JSON API is how you specify how different pieces of data are related to each other. However, your server is not always perfectly aligned with the JSON API spec.

Learn how to deal with that by customizing the extractRelationship and extractRelationships methods.

Code

//serializers/quote.js
import DS from 'ember-data';

export default DS.JSONAPISerializer.extend({
  // extractRelationships(modelClass, resourceHash){
  //   if(resourceHash.relationships){
  //     resourceHash.relationships.book = resourceHash.relationships.perpetrator
  //     delete resourceHash.relationships.perpetrator
  //   }
  //   return this._super(...arguments)
  // },

  // the easier way to do relationship renames
  attrs: {
    'body': 'badthink',
    'book': 'perpetrator'
  },

  extractRelationship(relationshipHash){
    relationshipHash.data.id = relationshipHash.data.id.replace('book_', '')
    return this._super(...arguments)
  }
})

Transcript

Hey, and welcome back to our series on Ember Data Serializers. Today we’re going to go over the extractRelationship and extractRelationships methods. Now in order to understand what we’re going to be talking about today, you’ll need to have watched the last two episodes in the serializer series. So once you’ve gone and watched those, we’ll get started.

So how this episode is going to go is first we’re going to look at when and where the extractRelationship and extractRelationships methods get called and how they relate to each other. Then we’re going to go over a couple of examples of how data can deviate from JSON API in ways that are fixed by these two methods.

So let’s start by investigating where and when these two methods get called. So we’ll place these in here and we’ll be logging out whenever they’re called. And we’ll be doing the same within the books serializer as well.

So here we are in the singular quote page, and this is the order that we’ve visited the extractRelationships and extractRelationship methods. And this is the data that we’re processing. So I’ll show you how this data is processed and you’ll see it line up with these. So first we get our quote and it’s going to extract all the relationships from this quote. And then it’s going to... here it is. And then it’s going to find that there’s only one relationship. And so then it’s going to call extractRelationship singular for that. And here it’s a bit messy, but you can see it’s book and id 1, and that’s getting it from here. Then it’ll go to our includeds and it will try to extract relationships from each of these, and there’s only one so it’ll do it here. And there’s no relationshipsHash, so it won’t call anything else after that, it’s done. And this is that third one here.

So let’s analyze this for something a little bit larger. So this is our /books, and this is indeed a much, much larger data set, but the same analysis will hold through. So we have our extractRelationships plural for this first book, and then we have it singular for here. And even though there are four quotes, the quotes is only one relationship. And so it only calls the extractRelationship singular once here and it gives it back an array of 4 items. Then it repeats it for book 2 and 3. Then we get to extracting the relationships plural here for the quotes, and it calls it extractRelationships once for each of these and once again there are no relationships that we’re including on this, so it doesn’t call anything else after that.

One thing that’s interesting to note is that when we’re calling the extractRelationship here, we’re getting the quotes relationship for calling extractRelationship on book. So that’s important to know where to put it when you’re trying to affect things.

So now that we’ve seen where they’re called, let’s look at some of the problems that we can solve using them. So first up... so right now, our relationship it’s shown as book, but someone messed with our data and now it’s not a book that has a quote. It’s a perpetrator of badthink. So we’ve got to roll with the punches and figure out how to get this in.

So as you can see, this is where the book information is supposed to be, but it’s not showing up. So we’ll solve this in the extractRelationships method, in the quote. So we can see here that the resourceHash given to us here has relationships, and it has the relationship of perpetrator. Now we can use... knowing that, we can use something similar to how we change the attributes up here. So what we’ll do is we’ll take our resourceHash and the relationships, and then we’ll assign it to book. And what will we assign the book? Well, we’ll assign the thing that is currently stored under perpetrator. So if we removed the debugger and reload, we’ll see that it’s working. And of course it’s good etiquette to delete the part of the resourceHash that we are no longer using.

Our current solution is working great in the quotes page, but there is a bit of a problem on the books page. And so it says it can’t read property perpetrator of undefined. So what’s happening is for some reason, the relationships on the resourceHash is undefined, and it’s trying to call perpetrator on that. And what’s happening is here in the included array, these quotes... it’s calling extractRelationships on them, but there’s no relationships here, and so it’s null. So what we’ll do is we’ll wrap it in an if statement. So if the resourceHash has a relationshipsHash , then we’ll do this. And this makes both of our pages work.

So in extractRelationships, there’s a lot of stuff you can do. Basically anything on this resourceHash is yours to play around with. But for the common case of just renaming something like we have here, we can do the same thing as we did with our extractAttributes, rename, and just put it on the attrs hash. And so here, renaming book to perpetrator takes care of everything in here.

For our next challenge, we’ll see that someone has changed the id. In JSON API it’s supposed to be just the number, but here it’s book_ number. And so how can we fix this? Well, as you could probably guess, we’re going to use extractRelationship. And so this relationshipHash... let’s go ahead and pause it here and see what we have. So this is on relationshipHash.data.id . And notice in extractRelationship, we’re getting the relationshipHash for one relationship, and the resourceHash up here is for all the relationships on this specific model.

So we reload without the debugger and we see that without a fix it is messing up. It’s giving us an internal server error. But the fix here fortunately is relatively easy. So we have the relationshipHash and then the data and the id, and what we’re going to assign to that id is what was previously in the id but with a couple of changes, mainly that we’re replacing book_ with an empty string. It’s like what we did up here when we were extracting the id. So we’ll see that everything is working again.

So this has been our look at the extractRelationship and extractRelationships methods in the Ember Data Serializer. It’s a bit longer than our typical screencast, but that’s because it was a difficult subject and I hope you understand it a little bit better now. See you next time.

Introduction to Ember Data 2.0

Subscribe to our mailing list