title: Bookshelf.js Eager Loading Third Table
body: <p>I'm struggling with Bookshelf.js and I'm hoping someone can lend me a hand.</p>
  
  <p>I've customers who have contacts of various types (email address, facebook, skype, etc.,). So I split into three tables to normalize the types. I can't seem to find out how to properly query and eager load the type of contact. I can get the contacts themselves easy via </p>
  
  <pre><code>new Customer({id: 1}).fetch({withRelated: ['contacts']}).then((customer) =&gt; {
      console.log(customer.toJSON());
      })
  </code></pre>
  
  <p>But for the life of me I can't seem to figure out how to match those contacts to their respective types. Rails did a lot of this under the covers and BOY am I regretting that...</p>
  
  <p><strong>Tables</strong></p>
  
  <pre><code>customers = knex.schema.createTable('customers', function(t) {
    t.increments('id').primary();
    t.string('emailAddress').notNullable().unique();
    t.timestamps(true, true);
  });
  
  contacts = knex.schema.createTable('contacts', function(t) {
    t.increments('id').primary();
    t.string('value').notNullable();
    t.integer('contact_type_id').references('contact_types.id');
    t.string('contactable_type').notNullable();
    t.integer('contactable_id').notNullable();
  });
  
  contact_types = knex.schema.createTable('contact_types', function(t) {
    t.increments('id').primary();
    t.string('value').notNullable();
  });
  </code></pre>
  
  <p><strong>Models</strong></p>
  
  <pre><code>const Customer = bookshelf.Model.extend({
    tableName: 'customers',
    contacts: function() {
      return this.morphMany('Contact', constants.CONTACTABLE);
    }
  });
  
  const Contact = bookshelf.Model.extend({
    tableName: 'contacts',
    contactable: function() {
      return this.morphTo(constants.CONTACTABLE, 'Customer');
    },
  
    type: function() {
      return this.belongsTo('ContactType');
    }
  });
  
  const ContactType = bookshelf.Model.extend({
    tableName: 'contact_types',
  
    contacts: function() {
      return this.hasMany('Contact');
    }
  });
  </code></pre>