Skip to content
Add support for partial models to Ember Data.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
addon
app
config
tests
vendor
.bowerrc
.editorconfig
.ember-cli
.gitignore
.jshintrc
.npmignore
.travis.yml
.watchmanconfig
CHANGELOG.md
LICENSE.md
README.md
bower.json
ember-cli-build.js
index.js
package.json
testem.json

README.md

Ember-data-partial-model Build Status npm version Ember Observer Score

This addon adds support for partial records to Ember Data. Let's say your api for /users returns a shallow model like:

[{id:1, name: 'BMac'}, {id:2, name:'Seb'}]

but /users/1 returns a detailed model

{
  id:1,
  name: 'BMac'
  twitter: 'seb'
}

You can use this addon to define your User model as:

// app/models/user.js

import { PartialModel, partial } from 'ember-data-partial-model/utils/model';
const { attr } = DS;

export default PartialModel.extend({
  name: attr(),
  extended: partial('user', 'extended', {
    twitter: attr()
  })
});

This addon will modify your application adapter/serializer, so that accessing user.get('extended') or any of the extended properties will trigger a request for the detailed model. For example:

let users = await store.findAll('user'); // goes to /users
let user = users.objectAt(1);

user.get('extended') //goes to /users/1, returns a promise
user.get('twitter') //goes to /users/1, but is just an alias, so returns null initially, should not do in app code

Thus you are safe from race conditions when rendering users, even if you have not loaded the full user In your template you can do

{{user.twitter}}

and it will populate once the full user is loaded

Introduction Video

Introduction to Ember Data Partial Model

How to use

If you haven't customized any of your adapters, serializers or store, the addon will work out of the box. By default it uses JSONAPISerializer and JSONAPIAdapter.

If you made any customization, you will need to include proper mixins. For adapter:

// app/adapters/application.js

import DS from 'ember-data';
import PartialModelAdapter from 'ember-data-partial-model/mixins/adapter';
const { JSONAPIAdapter } = DS;

export default JSONAPIAdapter.extend(PartialModelAdapter);

For serializer (both JSONAPISerializer and RESTSerializer are available):

// app/serializers/application.js

import DS from 'ember-data';
import PartialModelJSONAPISerializer from 'ember-data-partial-model/mixins/jsonapi-serializer';
const { JSONAPISerializer } = DS;

export default JSONAPISerializer.extend(PartialModelJSONAPISerializer);

or

// app/serializers/application.js

import DS from 'ember-data';
import PartialModelRESTSerializer from 'ember-data-partial-model/mixins/rest-serializer';
const { RESTSerializer } = DS;

export default RESTSerializer.extend(PartialModelRESTSerializer);

For store:

// app/services/store.js

import DS from 'ember-data';
import PartialModelStore from 'ember-data-partial-model/mixins/store';
const { Store } = DS;

export default Store.extend(PartialModelStore, {});

Supporting custom serializers

If you are using different serializer than REST or JSONAPI, you can create custom mixin to support it, you will just need to provide some functions for handling logic specific to your serializer. The basic layout is the following:

import Ember from 'ember';
import baseSerializerMixin from 'ember-data-partial-model/mixins/base-serializer';
const { Mixin } = Ember;

export default Mixin.create(baseSerializerMixin, {
  _normalizePartialRelationship: function(modelClass, resourceHash, descriptor) {
    // add this function to handle normalization of partial extension as a relationship.
  },

  _copyAttributesFromPartialToParent: function(serializedHash, partialHash) {
    // add this function to handle copying attributes from partial extension to top-level hash.
  },
});

Extending partial serializers

You can provide extensions and list of mixins to be applied for partial serializers. If you defined extended partial in user model like this:

// app/models/user.js

import { PartialModel, partial } from 'ember-data-partial-model/utils/model';
const { attr } = DS;

export default PartialModel.extend({
  name: attr(),
  extended: partial('user', 'extended', {
    twitter: attr(),
    clients: hasMany('client', { async: false })
  })
});

add you want to make clients relationship embedded and serialize all clients records when serializing user model, you could customize user serializer the following way:

// app/serializers/user.js

import Ember from 'ember';
import DS from 'ember-data';
import ApplicationSerializer from './application';

const { EmbeddedRecordsMixin } = DS;
const { Mixin } = Ember;

export default ApplicationSerializer.extend({
  partialSerializersExtensions: {
    extended: {
      attrs: {
        clients: { embedded: 'always' }
      }
    }
  },

  partialSerializersMixins: {
    extended: [EmbeddedRecordsMixin]
  }
});

All extensions defined inside partialSerializersExtensions will be copied for given partial and all mixins defined in partialSerializersMixins will be used when defining partial serializer.

Installation

  • git clone this repository
  • npm install
  • bower install

Running

Running Tests

  • ember test
  • ember test --server

Building

  • ember build

For more information on using ember-cli, visit http://www.ember-cli.com/.

You can’t perform that action at this time.