Search code examples
javascriptember.jsember-cliember-cli-mirage

Ember CLI Mirage: 2 level sideloaded response


I'm having some difficulty with modeling this relationship. Can someone please help?

A Tenant has an App

An App has a Brand

The big gotcha is 2 levels of side loading. My current API returns a response as follows:

{
  "tenants": [
      {
        "app_id": "app_001",
        "id": 1,
        "name": "Illya_no_delete",
      }
    ],
  "app": [
    {
      "brand_id": "brand_001",
      "id": "app_001",
      "name": "updated test client 2 name",
    }
  ],
  "brands": [
    {
      "id": "brand_001",
      "app_id": "app_001"
    }
  ]
}

I've set my models as:

// models/tenant.js
export default Model.extend({
  app: belongsTo('app'),
});


// mirage/models/app.js
export default Model.extend({
  brand: belongsTo('brand'),
  tenant: belongsTo('tenant')
});

// mirage/models/brand.js
export default Model.extend({
  app: belongsTo('app')
});

I've set my serializers as:

// mirage/serializers/app.js
export default ApplicationSerializer.extend({
  include: ['brand']
});

// mirage/serializers/tenant.js
export default ApplicationSerializer.extend({
  include: ['app']
});

I've set my scenario as:

// mirage/scenarios/default.js
let brand = server.create('brand');
let app = server.create('app', {brand: brand});
server.createList('tenant', 10, {app: app});

Unfortunately my generated response does NOT return a side-loaded brand object. I see all my other objects:

{
  tenant: {
    id: 1,
    app_id: 2
  },
  apps: [
    {
      id: 2,
      brand_id: null,
      tenant_id: 1
    }
  ]
}

Any suggestions on what I need to do to get 'brands' to appear?


Solution

  • To anyone interested, here's a solution that worked for me based on Sam Selikoff's comment. Open to feedback:

    Models:

    // models/tenant.js
    export default Model.extend({
      app: belongsTo('app'),
      brand: belongsTo('brand'),
    });
    
    // mirage/models/app.js
    export default Model.extend({
      tenant: belongsTo('tenant')
    });
    
    // mirage/models/brand.js
    export default Model.extend({
    
    });
    

    Serializers:

    // mirage/serializers/tenant.js
    export default ApplicationSerializer.extend({
      include: ['app', 'brand'],
    
      serialize() {
        let json = ApplicationSerializer.prototype.serialize.apply(this, arguments);
        if (json.brands.length > 0) {
          let brandId = json.brands[0].id;
          json.applications[0].brand_id = brandId;
        }
        return json;
      }
    });
    

    Default Scenario:

    // mirage/scenarios/default.js
    let brand = server.create('brand');
    let app = server.create('app');
    server.createList('tenant', 10, {app: app, brand: brand});
    

    Response:

    {
      tenant: {
        id: 1,
        app_id: 2
      },
      apps: [
        {
          id: 2,
          brand_id: 3,
          tenant_id: 1
        }
      ],
      brand: [
        {
          id: 3
        }
      ]
    }