From e5d803038650b7ff4cc46b267e8e076357ea373f Mon Sep 17 00:00:00 2001 From: Andy Crum Date: Fri, 2 Oct 2015 16:17:29 -0700 Subject: [PATCH] [BUGFIX] Do not deserialize when a relationship named type exists 69dca0c fixed this for attributes named 'type', but the RESTSerializer was still trying to deserialize relationships with that name as polymorphic, which was causing errors for anyone having a domain model called "Type". --- .../lib/serializers/rest-serializer.js | 4 +-- .../serializers/rest-serializer-test.js | 34 +++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/packages/ember-data/lib/serializers/rest-serializer.js b/packages/ember-data/lib/serializers/rest-serializer.js index 60b2a58b888..17ceff90a3f 100644 --- a/packages/ember-data/lib/serializers/rest-serializer.js +++ b/packages/ember-data/lib/serializers/rest-serializer.js @@ -149,7 +149,7 @@ var RESTSerializer = JSONSerializer.extend({ let modelClass = store.modelFor(modelName); let serializer = store.serializerFor(modelName); - const primaryHasTypeAttribute = get(modelClass, 'attributes').get('type'); + const primaryHasTypeAttribute = get(modelClass, 'attributes').get('type') || get(modelClass, 'relationshipsByName').get('type'); /*jshint loopfunc:true*/ arrayHash.forEach((hash) => { let { data, included } = this._normalizePolymorphicRecord(store, hash, prop, modelClass, serializer, primaryHasTypeAttribute); @@ -162,7 +162,7 @@ var RESTSerializer = JSONSerializer.extend({ return documentHash; }, - _normalizePolymorphicRecord(store, hash, prop, primaryModelClass, primarySerializer, primaryHasTypeAttribute) { + _normalizePolymorphicRecord: function(store, hash, prop, primaryModelClass, primarySerializer, primaryHasTypeAttribute) { let serializer, modelClass; // Support polymorphic records in async relationships if (!primaryHasTypeAttribute && hash.type && store._hasModelFor(this.modelNameFromPayloadKey(hash.type))) { diff --git a/packages/ember-data/tests/integration/serializers/rest-serializer-test.js b/packages/ember-data/tests/integration/serializers/rest-serializer-test.js index 13fa5b56dfa..ff043de2c28 100644 --- a/packages/ember-data/tests/integration/serializers/rest-serializer-test.js +++ b/packages/ember-data/tests/integration/serializers/rest-serializer-test.js @@ -1,4 +1,4 @@ -var HomePlanet, league, SuperVillain, EvilMinion, YellowMinion, DoomsdayDevice, Comment, Basket, env; +var HomePlanet, league, SuperVillain, EvilMinion, YellowMinion, DoomsdayDevice, Comment, Basket, Container, env; var run = Ember.run; module("integration/serializer/rest - RESTSerializer", { @@ -33,6 +33,10 @@ module("integration/serializer/rest - RESTSerializer", { type: DS.attr('string'), size: DS.attr('number') }); + Container = DS.Model.extend({ + type: DS.belongsTo('basket', { async: true }), + volume: DS.attr('string') + }); env = setupStore({ superVillain: SuperVillain, homePlanet: HomePlanet, @@ -40,7 +44,8 @@ module("integration/serializer/rest - RESTSerializer", { yellowMinion: YellowMinion, doomsdayDevice: DoomsdayDevice, comment: Comment, - basket: Basket + basket: Basket, + container: Container }); env.store.modelFor('super-villain'); env.store.modelFor('home-planet'); @@ -49,6 +54,7 @@ module("integration/serializer/rest - RESTSerializer", { env.store.modelFor('doomsday-device'); env.store.modelFor('comment'); env.store.modelFor('basket'); + env.store.modelFor('container'); }, teardown: function() { @@ -619,3 +625,27 @@ test("don't polymorphically deserialize base on the type key in payload when a t strictEqual(clashingRecord.get('type'), 'yellowMinion'); strictEqual(clashingRecord.get('size'), 10); }); + +test("don't polymorphically deserialize based on the type key in payload when a relationship exists named type", function() { + env.registry.register('serializer:application', DS.RESTSerializer.extend({ + isNewSerializerAPI: true + })); + + env.adapter.findRecord = () => { + return { + containers: [{ id: 42, volume: '10 liters', type: 1 }], + baskets: [{ id: 1, size: 4 }] + }; + }; + + run(function() { + env.store.findRecord('container', 42).then((container) => { + strictEqual(container.get('volume'), '10 liters'); + return container.get('type'); + }).then((basket) => { + ok(basket instanceof Basket); + equal(basket.get('size'), 4); + }); + }); + +});