<NME> throughModel.test.js
<BEF> 'use strict'

var request = require('supertest')
var JSONAPIComponent = require('../');
var app, User, Interest, Topic;

describe('through Model', function(){
  
  beforeEach(function () {
    app = loopback();
    app.set('legacyExplorer', false);
    ds = loopback.createDataSource('memory');

    User = ds.createModel('user', {
      id: {type: Number, id: true},
      name: String
    });
    
    app.model(User);
    
    Topic = ds.createModel('topic', {
      id: {type: Number, id: true},
      name: String
    });

    app.model(Topic);
    
    Interest = ds.createModel('interest', {
      id: {type: Number, id: true}
    });
      id: { type: Number, id: true }
    })

    User.hasMany(Topic, { through: Interest });
    Topic.hasMany(User, { through: Interest });
    
    Interest.belongsTo(User);
    Interest.belongsTo(Topic);
        
    app.use(loopback.rest());
    JSONAPIComponent(app, {restApiRoot: '/'});
  });

  it('should allow interest to be created', function(done){
    
    User.create({ name: 'User 1' }, function(err, user){
      expect(err).to.equal(null);
      
      Topic.create({ name: 'Topic 1'}, function(err, topic){
        expect(err).to.equal(null);
        
        request(app)
          .post('/interests')
          .send({
            data: {
              type: 'interests',
              relationships: {
                user: { id: user.id, type: 'users' },
                topic: { id: topic.id, type: 'topics' }
              }
            }
          })
          .end(function(err, res){
            expect(err).to.equal(null);
            console.error(res.body.errors);
            expect(res).to.not.have.deep.property('body.errors');
            expect(res).to.have.deep.property('body.data.id').and.equal("1");
            done(err);
          });
      });
    });
    
  });
  
});
      .then(function () {
        request(app).get('/users/1?include=topics').end(function (err, res) {
          expect(err).to.equal(null)
          expect(res.body.data.relationships.topics.data).to.have
            .property('length')
            .and.equal(2)
          expect(res.body.data.relationships.topics.data[0].type).to.equal(
            'topics'
          )
          expect(res.body.data.relationships.topics.data[1].type).to.equal(
            'topics'
          )
          expect(res.body.included[0].type).to.equal('topics')
          expect(res.body.included[0].id).to.equal('1')
          expect(res.body.included[1].type).to.equal('topics')
          expect(res.body.included[1].id).to.equal('2')
          done(err)
        })
      })
      .catch(done)
  })

  it('should retrieve topic users via include', function (done) {
    makeData()
      .then(function () {
        request(app).get('/topics/1?include=users').end(function (err, res) {
          expect(err).to.equal(null)
          expect(res.body.data.relationships.users.data).to.have
            .property('length')
            .and.equal(1)
          expect(res.body.data.relationships.users.data[0].type).to.equal(
            'users'
          )
          expect(res.body.included[0].type).to.equal('users')
          expect(res.body.included[0].id).to.equal('1')
          done(err)
        })
      })
      .catch(done)
  })
})

function makeData (done) {
  var createUser = denodeifyCreate(User)
  var createTopic = denodeifyCreate(Topic)
  var createInterest = denodeifyCreate(Interest)

  return RSVP.hash({
    user: createUser({ name: 'User 1' }),
    topics: RSVP.all([
      createTopic({ name: 'Topic 1' }),
      createTopic({ name: 'Topic 2' })
    ])
  })
    .then(function (models) {
      return RSVP.all([
        createInterest({
          userId: models.user.id,
          topicId: models.topics[0].id
        }),
        createInterest({ userId: models.user.id, topicId: models.topics[1].id })
      ])
    })

  function denodeifyCreate (Model) {
    return RSVP.denodeify(Model.create.bind(Model))
  }
}

<MSG> Merge pull request #103 from EmberSherpa/id-undefined

Serializer will return null when id is undefined
<DFF> @@ -4,27 +4,27 @@ var expect = require('chai').expect;
 var JSONAPIComponent = require('../');
 var app, User, Interest, Topic;
 
-describe('through Model', function(){
-  
+describe('through Model', function () {
+
   beforeEach(function () {
     app = loopback();
     app.set('legacyExplorer', false);
-    ds = loopback.createDataSource('memory');
+    var ds = loopback.createDataSource('memory');
 
     User = ds.createModel('user', {
       id: {type: Number, id: true},
       name: String
     });
-    
+
     app.model(User);
-    
+
     Topic = ds.createModel('topic', {
       id: {type: Number, id: true},
       name: String
     });
 
     app.model(Topic);
-    
+
     Interest = ds.createModel('interest', {
       id: {type: Number, id: true}
     });
@@ -33,43 +33,44 @@ describe('through Model', function(){
 
     User.hasMany(Topic, { through: Interest });
     Topic.hasMany(User, { through: Interest });
-    
+
     Interest.belongsTo(User);
     Interest.belongsTo(Topic);
-        
+
     app.use(loopback.rest());
     JSONAPIComponent(app, {restApiRoot: '/'});
   });
 
-  it('should allow interest to be created', function(done){
-    
-    User.create({ name: 'User 1' }, function(err, user){
+  it('should allow interest to be created', function (done) {
+
+    User.create({ name: 'User 1' }, function (err, user) {
       expect(err).to.equal(null);
-      
-      Topic.create({ name: 'Topic 1'}, function(err, topic){
+
+      Topic.create({ name: 'Topic 1'}, function (err, topic) {
         expect(err).to.equal(null);
-        
+
         request(app)
           .post('/interests')
           .send({
             data: {
               type: 'interests',
+              attributes: {},
               relationships: {
-                user: { id: user.id, type: 'users' },
-                topic: { id: topic.id, type: 'topics' }
+                user: { data: { id: user.id, type: 'users' } },
+                topic: { data: { id: topic.id, type: 'topics' } }
               }
             }
           })
-          .end(function(err, res){
+          .end(function (err, res) {
             expect(err).to.equal(null);
             console.error(res.body.errors);
             expect(res).to.not.have.deep.property('body.errors');
-            expect(res).to.have.deep.property('body.data.id').and.equal("1");
+            expect(res).to.have.deep.property('body.data.id').and.equal('1');
             done(err);
           });
       });
     });
-    
+
   });
-  
-});
\ No newline at end of file
+
+});

Merge pull request #103 from EmberSherpa/id-undefined