From b7a19f912f94e638806eaf39c42f3bedd123dbc9 Mon Sep 17 00:00:00 2001 From: Christoffer Persson Date: Sat, 6 Jun 2015 01:00:10 +0300 Subject: [PATCH] Implement extractMeta for new Serializer API --- .../lib/serializers/json-serializer.js | 26 +++++++++- .../lib/serializers/rest-serializer.js | 26 ++++++---- .../serializers/json-serializer-new-test.js | 49 +++++++++---------- .../serializers/rest-serializer-new-test.js | 19 +++++++ 4 files changed, 83 insertions(+), 37 deletions(-) diff --git a/packages/ember-data/lib/serializers/json-serializer.js b/packages/ember-data/lib/serializers/json-serializer.js index 655fb65af2d..6a205e7e319 100644 --- a/packages/ember-data/lib/serializers/json-serializer.js +++ b/packages/ember-data/lib/serializers/json-serializer.js @@ -425,7 +425,11 @@ export default Serializer.extend({ included: [] }; - payload = this.normalizePayload(payload); + let meta = this.extractMeta(store, primaryModelClass, payload); + if (meta) { + Ember.assert('The `meta` returned from `extractMeta` has to be an object, not "' + Ember.typeOf(meta) + '".', Ember.typeOf(meta) === 'object'); + documentHash.meta = meta; + } if (isSingle) { let { data } = this.normalize(primaryModelClass, payload); @@ -1443,6 +1447,10 @@ export default Serializer.extend({ @param {Object} payload */ extractMeta: function(store, typeClass, payload) { + if (Ember.FEATURES.isEnabled('ds-new-serializer-api') && this.get('isNewSerializerAPI')) { + return _newExtractMeta.apply(this, arguments); + } + if (payload && payload.meta) { store.setMetadataFor(typeClass, payload.meta); delete payload.meta; @@ -1592,3 +1600,19 @@ function _newNormalize(modelClass, resourceHash) { return { data }; } + +/* + @method _newExtractMeta + @param {DS.Store} store + @param {DS.Model} modelClass + @param {Object} payload + @return {Object} + @private +*/ +function _newExtractMeta(store, modelClass, payload) { + if (payload && payload.hasOwnProperty('meta')) { + let meta = payload.meta; + delete payload.meta; + return meta; + } +} diff --git a/packages/ember-data/lib/serializers/rest-serializer.js b/packages/ember-data/lib/serializers/rest-serializer.js index da97a9d4350..70136a19770 100644 --- a/packages/ember-data/lib/serializers/rest-serializer.js +++ b/packages/ember-data/lib/serializers/rest-serializer.js @@ -236,11 +236,17 @@ var RESTSerializer = JSONSerializer.extend({ @private */ _normalizeResponse: function(store, primaryModelClass, payload, id, requestType, isSingle) { - var document = { + let documentHash = { data: null, included: [] }; + let meta = this.extractMeta(store, primaryModelClass, payload); + if (meta) { + Ember.assert('The `meta` returned from `extractMeta` has to be an object, not "' + Ember.typeOf(meta) + '".', Ember.typeOf(meta) === 'object'); + documentHash.meta = meta; + } + Ember.keys(payload).forEach((prop) => { var modelName = prop; var forcedSecondary = false; @@ -296,14 +302,14 @@ var RESTSerializer = JSONSerializer.extend({ */ if (isPrimary && Ember.typeOf(value) !== 'array') { let { data, included } = this.normalize(primaryModelClass, value, prop); - document.data = data; - document.included.push(...included); + documentHash.data = data; + documentHash.included.push(...included); return; } let { data, included } = this.normalizeArray(store, typeName, value, prop); - document.included.push(...included); + documentHash.included.push(...included); if (isSingle) { /*jshint loopfunc:true*/ @@ -319,24 +325,24 @@ var RESTSerializer = JSONSerializer.extend({ in the array */ var isUpdatedRecord = isPrimary && coerceId(resource.id) === id; - var isFirstCreatedRecord = isPrimary && !id && !document.data; + var isFirstCreatedRecord = isPrimary && !id && !documentHash.data; if (isFirstCreatedRecord || isUpdatedRecord) { - document.data = resource; + documentHash.data = resource; } else { - document.included.push(resource); + documentHash.included.push(resource); } }); } else { if (isPrimary) { - document.data = data; + documentHash.data = data; } else { - document.included.push(...data); + documentHash.included.push(...data); } } }); - return document; + return documentHash; }, /** diff --git a/packages/ember-data/tests/integration/serializers/json-serializer-new-test.js b/packages/ember-data/tests/integration/serializers/json-serializer-new-test.js index 0e0b2caa58f..23411fbd046 100644 --- a/packages/ember-data/tests/integration/serializers/json-serializer-new-test.js +++ b/packages/ember-data/tests/integration/serializers/json-serializer-new-test.js @@ -76,6 +76,29 @@ if (Ember.FEATURES.isEnabled('ds-new-serializer-api')) { deepEqual(post.data.relationships.comments.data, [{ id: "1", type: "comment" }, { id: "2", type: "comment" }]); }); + test('normalizeSingleResponse should extract meta using extractMeta', function() { + env.registry.register("serializer:post", TestSerializer.extend({ + extractMeta: function(store, modelClass, payload) { + let meta = this._super(...arguments); + meta.authors.push('Tomhuda'); + return meta; + } + })); + + var jsonHash = { + id: "1", + title_payload_key: "Rails is omakase", + my_comments: [1, 2], + meta: { + authors: ['Tomster'] + } + }; + + var post = env.container.lookup("serializer:post").normalizeSingleResponse(env.store, Post, jsonHash, '1', 'find'); + + deepEqual(post.meta.authors, ['Tomster', 'Tomhuda']); + }); + test("Serializer should respect the primaryKey attribute when extracting records", function() { env.registry.register('serializer:post', TestSerializer.extend({ primaryKey: '_ID_' @@ -120,32 +143,6 @@ if (Ember.FEATURES.isEnabled('ds-new-serializer-api')) { deepEqual(post.data.relationships.comments.data, [{ id: "1", type: "comment" }]); }); - test("normalizePayload is called during normalizeSingleResponse", function() { - var counter = 0; - - env.registry.register('serializer:post', TestSerializer.extend({ - normalizePayload: function(payload) { - counter++; - return payload.response; - } - })); - - var jsonHash = { - response: { - id: 1, - title: "Rails is omakase" - } - }; - - run(function() { - post = env.container.lookup("serializer:post").normalizeSingleResponse(env.store, Post, jsonHash, '1', 'find'); - }); - - equal(counter, 1); - equal(post.data.id, "1"); - equal(post.data.attributes.title, "Rails is omakase"); - }); - test("Calling normalize should normalize the payload (only the passed keys)", function () { expect(1); var Person = DS.Model.extend({ diff --git a/packages/ember-data/tests/integration/serializers/rest-serializer-new-test.js b/packages/ember-data/tests/integration/serializers/rest-serializer-new-test.js index ca85ab4c304..866322b4c25 100644 --- a/packages/ember-data/tests/integration/serializers/rest-serializer-new-test.js +++ b/packages/ember-data/tests/integration/serializers/rest-serializer-new-test.js @@ -105,6 +105,25 @@ if (Ember.FEATURES.isEnabled('ds-new-serializer-api')) { }); }); + test('normalizeArrayResponse should extract meta using extractMeta', function() { + env.registry.register("serializer:home-planet", TestSerializer.extend({ + extractMeta: function(store, modelClass, payload) { + let meta = this._super(...arguments); + meta.authors.push('Tomhuda'); + return meta; + } + })); + + var jsonHash = { + meta: { authors: ['Tomster'] }, + home_planets: [{ id: "1", name: "Umber", superVillains: [1] }] + }; + + var json = env.container.lookup("serializer:home-planet").normalizeArrayResponse(env.store, HomePlanet, jsonHash, null, 'findAll'); + + deepEqual(json.meta.authors, ['Tomster', 'Tomhuda']); + }); + test("normalizeArrayResponse warning with custom modelNameFromPayloadKey", function() { var homePlanets; env.restNewSerializer.modelNameFromPayloadKey = function(root) {