Skip to content

Commit

Permalink
Use the correct modelClass and serializer to extract a polymorphic ty…
Browse files Browse the repository at this point in the history
…pe when normalizing async relationships.

Closes #3547
  • Loading branch information
bmac committed Aug 20, 2015
1 parent 145ccc9 commit b7f7b7a
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 4 deletions.
19 changes: 16 additions & 3 deletions packages/ember-data/lib/serializers/rest-serializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ var RESTSerializer = JSONSerializer.extend({
let serializer = store.serializerFor(modelName);

arrayHash.forEach((hash) => {
let { data, included } = serializer.normalize(modelClass, hash, prop);
let { data, included } = this._normalizePolymorphicRecord(store, hash, prop, modelClass, serializer);
documentHash.data.push(data);
if (included) {
documentHash.included.push(...included);
Expand All @@ -159,7 +159,20 @@ var RESTSerializer = JSONSerializer.extend({
return documentHash;
},

/**
_normalizePolymorphicRecord(store, hash, prop, primaryModelClass, primarySerializer) {
let serializer, modelClass;
// Support polymorphic records in async relationships
if (hash.type && store._hasModelFor(this.modelNameFromPayloadKey(hash.type))) {
serializer = store.serializerFor(hash.type);
modelClass = store.modelFor(hash.type);
} else {
serializer = primarySerializer;
modelClass = primaryModelClass;
}
return serializer.normalize(modelClass, hash, prop);
},

/*
@method _normalizeResponse
@param {DS.Store} store
@param {DS.Model} primaryModelClass
Expand Down Expand Up @@ -241,7 +254,7 @@ var RESTSerializer = JSONSerializer.extend({
```
*/
if (isPrimary && Ember.typeOf(value) !== 'array') {
let {data, included} = this.normalize(primaryModelClass, value, prop);
let { data, included } = this._normalizePolymorphicRecord(store, value, prop, primaryModelClass, this);
documentHash.data = data;
if (included) {
documentHash.included.push(...included);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ module("integration/serializer/rest - RESTSerializer", {
superVillain: DS.belongsTo('super-villain', { async: false }),
name: DS.attr('string')
});
YellowMinion = EvilMinion.extend();
YellowMinion = EvilMinion.extend({
eyes: DS.attr('number')
});
DoomsdayDevice = DS.Model.extend({
name: DS.attr('string'),
evilMinion: DS.belongsTo('evil-minion', { polymorphic: true, async: true })
Expand Down Expand Up @@ -461,6 +463,81 @@ test('serializeIntoHash uses payloadKeyFromModelName to normalize the payload ro
});
});

test('normalizeResponse with async polymorphic belongsTo', function() {
env.registry.register('serializer:application', DS.RESTSerializer.extend({
isNewSerializerAPI: true
}));
var store = env.store;
env.adapter.findRecord = () => {
return {
doomsdayDevices: [{
id: 1,
name: "DeathRay",
links: {
evilMinion: '/doomsday-device/1/evil-minion'
}
}]
};
};

env.adapter.findBelongsTo = () => {
return {
evilMinion: {
id: 1,
type: 'yellowMinion',
name: 'Alex',
eyes: 3
}
};
};
run(function() {
store.findRecord('doomsday-device', 1).then((deathRay) => {
return deathRay.get('evilMinion');
}).then((evilMinion) => {
equal(evilMinion.get('eyes'), 3);
});
});
});

test('normalizeResponse with async polymorphic hasMany', function() {
SuperVillain.reopen({ evilMinions: DS.hasMany('evil-minion', { async: true, polymorphic: true }) });
env.registry.register('serializer:application', DS.RESTSerializer.extend({
isNewSerializerAPI: true
}));
var store = env.store;
env.adapter.findRecord = () => {
return {
superVillains: [{
id: "1",
firstName: "Yehuda",
lastName: "Katz",
links: {
evilMinions: '/super-villain/1/evil-minions'
}
}]
};
};

env.adapter.findHasMany = () => {
return {
evilMinion: [{
id: 1,
type: 'yellowMinion',
name: 'Alex',
eyes: 3
}]
};
};
run(function() {
store.findRecord('super-villain', 1).then((superVillain) => {
return superVillain.get('evilMinions');
}).then((evilMinions) => {
ok(evilMinions.get('firstObject') instanceof YellowMinion);
equal(evilMinions.get('firstObject.eyes'), 3);
});
});
});

test("normalizeResponse can load secondary records of the same type without affecting the query count", function() {
var jsonHash = {
comments: [{ id: "1", body: "Parent Comment", root: true, children: [2, 3] }],
Expand Down

0 comments on commit b7f7b7a

Please sign in to comment.