An Engineer in Atlanta

Ember, Ember-Data, RESTSerializer and Rails 2.3

May 30, 2014

I recently started trying to port portions of our main application into an Ember application. This has been educational, to say the least. One of the snags I hit early on was how to get data out of our old Rails 2.3 app and into a form that ember-data could read. After much nail-biting, I ran across the DS.RESTSerializer class and it’s extractArray and extractSingle functions, and how to extend it in such a way that when data comes in, it is massaged into the format that ember-data is expecting.

The main thing to remember about ember-data is it is expecting a root element (I believe this is easier in Rails 3+ due to the ActiveModelSerializer gem, but due to dependencies, I couldn’t utilize this). So while my app was returning data that looked like this:

[
  {
    title: "Something cool",
    body: "lots of stuff to say about something cool"
  }
]

Ember-data wants it in something like this:

{
  posts: [
    {
      title: "Something cool",
      body: " lots of stuff to say about something cool"
    }
  ]
}

You might be thinking, “Just use ActiveRecord::Base.includerootinjson = true!” The problem is when you start nesting stuff inside (using the tojson(:include => :comments) syntax) it just completely broke ember-data, and I spent way too much time trying to get it to work. So finally I ran across the API documentation and adapted the example they gave to turn it into something that finally worked. It looks something like this:

App.PostSerializer = DS.RESTSerializer.extend({
  extractArray: function(store, type, payload, id, requestType) {
    var posts = payload;
    var comments = [];;

    posts.forEach(function(post) {
      var commentIds = [];
      if (post.comments) {
        post.comments.forEach(function(comment) {
          commentIds.push(comment.id);
          comments.push(comment);
        });
      }
      post.comments = commentIds;
    });

    payload = { posts: posts, comments: comments };

    return this._super(store, type, payload, id, requestType);
  }
});

This assumes each post item includes all of it’s related comments nested within the JSON. The serializer then walks through all the comments in each post and adds the comment.id to the commentIds array. It then adds the comment itself to the comments array. Finally it sets the post.comments = commentIds. It then sets the payload to have root tags for each section, as ember-data seems to want.

I believe there are other ways to do this, but I haven’t been able to figure them out.


Dan Smith

Written by Dan Smith who lives and works in Atlanta doing random stuff. You should follow him on Twitter