Skip to content

Commit

Permalink
[BUGFIX beta] serializePolymorphicType uses keyForPolymorphicType
Browse files Browse the repository at this point in the history
Currently `keyForAttribute` is used to get the key under which the type
of a polymorphic record is serialized. This is not correct, as the new
`keyForPolymorphicType` hook should be used.

This commit uses the new hook and falls back to the previous vesion, if
the key generated via the old method (keyForAttribute) is different to
the new version and the `keyForPolymorphicType` has not been
overwritten. A deprecation warning is logged if this is the case.
  • Loading branch information
pangratz committed Oct 20, 2015
1 parent 1d85e5c commit 4f7cf7b
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 3 deletions.
25 changes: 22 additions & 3 deletions packages/ember-data/lib/serializers/rest-serializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,7 @@ var RESTSerializer = JSONSerializer.extend({

/**
You can use this method to customize how polymorphic objects are serialized.
By default the JSON Serializer creates the key by appending `Type` to
By default the REST Serializer creates the key by appending `Type` to
the attribute and value from the model's camelcased model name.
@method serializePolymorphicType
Expand All @@ -714,11 +714,30 @@ var RESTSerializer = JSONSerializer.extend({
serializePolymorphicType: function(snapshot, json, relationship) {
var key = relationship.key;
var belongsTo = snapshot.belongsTo(key);
var typeKey = this.keyForPolymorphicType(key, relationship.type, 'serialize');

// old way of getting the key for the polymorphic type
key = this.keyForAttribute ? this.keyForAttribute(key, "serialize") : key;
key = `${key}Type`;

// The old way of serializing the type of a polymorphic record used
// `keyForAttribute`, which is not correct. The next code checks if the old
// way is used and if it differs from the new way of using
// `keyForPolymorphicType`. If this is the case, a deprecation warning is
// logged and the old way is restored (so nothing breaks).
if (key !== typeKey && this.keyForPolymorphicType === RESTSerializer.prototype.keyForPolymorphicType) {
Ember.deprecate("The key to serialize the type of a polymorphic record is created via keyForAttribute which has been deprecated. Use the keyForPolymorphicType hook instead.", false, {
id: 'ds.rest-serializer.deprecated-key-for-polymorphic-type',
until: '3.0.0'
});

typeKey = key;
}

if (Ember.isNone(belongsTo)) {
json[key + "Type"] = null;
json[typeKey] = null;
} else {
json[key + "Type"] = Ember.String.camelize(belongsTo.modelName);
json[typeKey] = camelize(belongsTo.modelName);
}
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,46 @@ test('serializeBelongsTo with async polymorphic', function() {
deepEqual(json, expected, 'returned JSON is correct');
});

test('serializeBelongsTo logs deprecation when old behavior for getting polymorphic type key is used', function() {
var evilMinion, doomsdayDevice;
var json = {};
var expected = { evilMinion: '1', myCustomKeyType: 'evilMinion' };

env.restSerializer.keyForAttribute = function() {
return 'myCustomKey';
};

run(function() {
evilMinion = env.store.createRecord('evil-minion', { id: 1, name: 'Tomster' });
doomsdayDevice = env.store.createRecord('doomsday-device', { id: 2, name: 'Yehuda', evilMinion: evilMinion });
});

expectDeprecation(function() {
env.restSerializer.serializeBelongsTo(doomsdayDevice._createSnapshot(), json, { key: 'evilMinion', options: { polymorphic: true, async: true } });
}, "The key to serialize the type of a polymorphic record is created via keyForAttribute which has been deprecated. Use the keyForPolymorphicType hook instead.");

deepEqual(json, expected, 'returned JSON is correct');
});

test('keyForPolymorphicType can be used to overwrite how the type of a polymorphic record is serialized', function() {
var evilMinion, doomsdayDevice;
var json = {};
var expected = { evilMinion: '1', typeForEvilMinion: 'evilMinion' };

env.restSerializer.keyForPolymorphicType = function() {
return 'typeForEvilMinion';
};

run(function() {
evilMinion = env.store.createRecord('evil-minion', { id: 1, name: 'Tomster' });
doomsdayDevice = env.store.createRecord('doomsday-device', { id: 2, name: 'Yehuda', evilMinion: evilMinion });
});

env.restSerializer.serializeBelongsTo(doomsdayDevice._createSnapshot(), json, { key: 'evilMinion', options: { polymorphic: true, async: true } });

deepEqual(json, expected, 'returned JSON is correct');
});

test('keyForPolymorphicType can be used to overwrite how the type of a polymorphic record is looked up for normalization', function() {
var json = {
doomsdayDevice: {
Expand Down

0 comments on commit 4f7cf7b

Please sign in to comment.