Skip to content

Commit

Permalink
Update to ember 1.13 serializer api.
Browse files Browse the repository at this point in the history
  • Loading branch information
benkonrath committed Jul 22, 2015
1 parent 8e2a605 commit 3bbce02
Show file tree
Hide file tree
Showing 16 changed files with 208 additions and 331 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ ember-django-adapter Changelog

Master
------
* [BREAKING ENHANCEMENT] Update to new Ember 1.13 serializer API
([#114](https://github.com/dustinfarris/ember-django-adapter/pull/114))
* [ENHANCEMENT] Add support for HyperlinkedRelatedFields.
* [INTERNAL] Updated ember-cli version to latest (1.13.1)
* [ENHANCEMENT] Adapter now supports ember-data 1.13.5
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ various backend APIs.

This adapter enables the use of [Django REST Framework][] as an API backend for
Ember Data. The addon is compatible with [ember-cli][] version 0.2.7 and higher, Ember 1.12.1 and
higher, and Ember Data v1.13.5.
higher, and Ember Data v1.13.6.


Community
Expand Down
141 changes: 54 additions & 87 deletions addon/serializers/drf.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,51 +10,47 @@ import Ember from 'ember';
* @class DRFSerializer
* @extends DS.RESTSerializer
*/
export default DS.RESTSerializer.extend({
/**
* Normalizes a part of the JSON payload returned by the server. This
* version simply calls addRelationshipsToLinks() before invoking
* the RESTSerializer's version.
*
* @method normalize
* @param {subclass of DS.Model} typeClass
* @param {Object} hash
* @param {String} prop
* @return {Object}
*/
normalize: function(typeClass, hash, prop) {
this.addRelationshipsToLinks(typeClass, hash);
return this._super(typeClass, hash, prop);
},
export default DS.JSONSerializer.extend({
// Remove this in our 2.0 release.
isNewSerializerAPI: true,

/**
* Adds relationships to the links hash as expected by the RESTSerializer.
* Returns the resource's relationships formatted as a JSON-API "relationships object".
*
* @method addRelationshipsToLinks
* @private
* @param {subclass of DS.Model} typeClass
* @param {Object} hash
* http://jsonapi.org/format/#document-resource-object-relationships
*
* This version adds a 'links'hash with relationship urls before invoking the
* JSONSerializer's version.
*
* @method extractRelationships
* @param {Object} modelClass
* @param {Object} resourceHash
* @return {Object}
*/
addRelationshipsToLinks: function(typeClass, hash) {
if (!hash.hasOwnProperty('links')) {
hash['links'] = {};
extractRelationships: function (modelClass, resourceHash) {
if (!resourceHash.hasOwnProperty('links')) {
resourceHash['links'] = {};
}

typeClass.eachRelationship(function(key, relationship) {
modelClass.eachRelationship(function(key, relationshipMeta) {
let payloadRelKey = this.keyForRelationship(key);
if (!hash.hasOwnProperty(payloadRelKey)) {

if (!resourceHash.hasOwnProperty(payloadRelKey)) {
return;
}
if (relationship.kind === 'hasMany' || relationship.kind === 'belongsTo') {

if (relationshipMeta.kind === 'hasMany' || relationshipMeta.kind === 'belongsTo') {
// Matches strings starting with: https://, http://, //, /
var payloadRel = hash[payloadRelKey];
var payloadRel = resourceHash[payloadRelKey];
if (!Ember.isNone(payloadRel) && !Ember.isNone(payloadRel.match) &&
typeof(payloadRel.match) === 'function' && payloadRel.match(/^((https?:)?\/\/|\/)\w/)) {
hash['links'][key] = hash[payloadRelKey];
delete hash[payloadRelKey];
resourceHash['links'][key] = resourceHash[payloadRelKey];
delete resourceHash[payloadRelKey];
}
}
}, this);

return this._super(modelClass, resourceHash);
},

/**
Expand All @@ -77,70 +73,41 @@ export default DS.RESTSerializer.extend({
},

/**
* `extractMeta` is used to deserialize any meta information in the
* adapter payload. By default Ember Data expects meta information to
* be located on the `meta` property of the payload object.
* Normalizes server responses for array or list data using the JSONSerializer's version
* of this function.
*
* @method extractMeta
* @param {DS.Store} store
* @param {subclass of DS.Model} type
* @param {Object} payload
*/
extractMeta: function(store, type, payload) {
if (payload && payload.results) {
// Sets the metadata for the type.
store.setMetadataFor(type, {
count: payload.count,
next: this.extractPageNumber(payload.next),
previous: this.extractPageNumber(payload.previous)
});

// Keep ember data from trying to parse the metadata as a records
delete payload.count;
delete payload.next;
delete payload.previous;
}
},

/**
* `extractSingle` is used to deserialize a single record returned
* from the adapter.
* If the payload has a results property, all properties that aren't in the results
* are added to the 'meta' hash so that Ember Data can use these properties for metadata.
* The next and previous pagination URLs are parsed to make it easier to paginate data
* in applications.
*
* @method extractSingle
* @method normalizeArrayResponse
* @param {DS.Store} store
* @param {subclass of DS.Model} type
* @param {DS.Model} primaryModelClass
* @param {Object} payload
* @param {String or Number} id
* @return {Object} json The deserialized payload
* @param {String|Number} id
* @param {String} requestType
* @return {Object} JSON-API Document
*/
extractSingle: function(store, type, payload, id) {
// Convert payload to json format expected by the RESTSerializer.
var convertedPayload = {};
convertedPayload[type.modelName] = payload;
return this._super(store, type, convertedPayload, id);
},
normalizeArrayResponse: function(store, primaryModelClass, payload, id, requestType) {
if (!Ember.isNone(payload) && payload.hasOwnProperty('results')) {
// Move DRF metadata to the meta hash.
let modifiedPayload = JSON.parse(JSON.stringify(payload.results));
let metadata = JSON.parse(JSON.stringify(payload));
delete metadata.results;
modifiedPayload['meta'] = metadata;

/**
* `extractArray` is used to deserialize an array of records
* returned from the adapter.
*
* @method extractArray
* @param {DS.Store} store
* @param {subclass of DS.Model} type
* @param {Object} payload
* @return {Array} array An array of deserialized objects
*/
extractArray: function(store, type, payload) {
// Convert payload to json format expected by the RESTSerializer.
// This function is being overridden instead of normalizePayload()
// because the `results` hash is only in lists of records.
var convertedPayload = {};
if (payload.results) {
convertedPayload[type.modelName] = payload.results;
} else {
convertedPayload[type.modelName] = payload;
// The next and previous pagination URLs are parsed to make it easier to paginate data in applications.
if (!Ember.isNone(modifiedPayload.meta['next'])) {
modifiedPayload.meta['next'] = this.extractPageNumber(modifiedPayload.meta['next']);
}
if (!Ember.isNone(modifiedPayload.meta['previous'])) {
modifiedPayload.meta['previous'] = this.extractPageNumber(modifiedPayload.meta['previous']);
}
return this._super(store, primaryModelClass, modifiedPayload, id, requestType);
}
return this._super(store, type, convertedPayload);

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

/**
Expand Down
4 changes: 2 additions & 2 deletions bower.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "ember-django-adapter",
"dependencies": {
"ember": "1.13.4",
"ember": "1.13.5",
"ember-cli-shims": "ember-cli/ember-cli-shims#0.0.3",
"ember-cli-test-loader": "ember-cli-test-loader#0.1.3",
"ember-data": "1.13.5",
"ember-data": "1.13.6",
"ember-load-initializers": "ember-cli/ember-load-initializers#0.1.5",
"ember-qunit": "0.4.1",
"ember-qunit-notifications": "0.0.7",
Expand Down
6 changes: 3 additions & 3 deletions config/ember-try.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ module.exports = {
{
name: 'ember-data-113-ember-112',
dependencies: {
'ember-data': '1.13.5',
'ember-data': '1.13.6',
'ember': '1.12.1'
}
},
{
name: 'ember-data-113-ember-113',
dependencies: {
'ember-data': '1.13.5',
'ember': '1.13.4'
'ember-data': '1.13.6',
'ember': '1.13.5'
}
}
]
Expand Down
2 changes: 1 addition & 1 deletion docs/coalesce-find-requests.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
When a record returns the IDs of records in a hasMany relationship, Ember Data
allows us to opt-in to combine these requests into a single request.

*Note:* Using [hyperlinked related fields](hyperlinked-related-fields.md) to retrieve related
**Note:** Using [hyperlinked related fields](hyperlinked-related-fields.md) to retrieve related
records in a single request is preferred over using coalesceFindRequests since there is a limit on
the number of records per request on read-only fields due to URL length restrictions.

Expand Down
2 changes: 1 addition & 1 deletion docs/hyperlinked-related-fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ related comments instead of one URL per related record:
}
```

*Note:* It is also possible to use the [Coalesce Find Requests](coalesce-find-requests.md)
**Note:** It is also possible to use the [Coalesce Find Requests](coalesce-find-requests.md)
feature to retrieve related records in a single request, however, this is the preferred
solution.

Expand Down
3 changes: 2 additions & 1 deletion docs/non-field-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ In case of several errors, the InvalidError.errors attribute will include
{ detail: 'error 2', meta { key: 'non_field_errors' } } //or whatever key name you configured
```

**note** we store the key for non-field errors in a meta object as this is non standard in the error object defined by the jsonapi spec
**Note:** We store the key for non-field errors in a meta object as this is non standard in the error
object defined by the JSON API spec.
Loading

0 comments on commit 3bbce02

Please sign in to comment.