Skip to content

Commit 4452605

Browse files
committed
fix deserialize an included relationship with alternativeKey
closes #103
1 parent eb8127a commit 4452605

File tree

2 files changed

+213
-33
lines changed

2 files changed

+213
-33
lines changed

lib/JSONAPISerializer.js

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -473,47 +473,74 @@ module.exports = class JSONAPISerializer {
473473
Object.keys(data.relationships).forEach((relationshipProperty) => {
474474
const relationship = data.relationships[relationshipProperty];
475475

476-
let relationshipKey = options.unconvertCase
476+
const relationshipKey = options.unconvertCase
477477
? this._convertCase(relationshipProperty, options.unconvertCase)
478478
: relationshipProperty;
479479

480-
// Support alternativeKey options for relationships
481-
if (
482-
options.relationships[relationshipKey] &&
483-
options.relationships[relationshipKey].alternativeKey
484-
) {
485-
relationshipKey = options.relationships[relationshipKey].alternativeKey;
486-
}
480+
const relationshipOptions = options.relationships[relationshipKey];
487481

488482
const deserializeFunction = (relationshipData) => {
489-
if (
490-
options.relationships[relationshipKey] &&
491-
options.relationships[relationshipKey].deserialize
492-
) {
493-
return options.relationships[relationshipKey].deserialize(relationshipData);
483+
if (relationshipOptions && relationshipOptions.deserialize) {
484+
return relationshipOptions.deserialize(relationshipData);
494485
}
495486
return relationshipData.id;
496487
};
497488

498489
if (relationship.data !== undefined) {
499490
if (Array.isArray(relationship.data)) {
491+
if (relationshipOptions && relationshipOptions.alternativeKey) {
492+
set(
493+
deserializedData,
494+
relationshipOptions.alternativeKey,
495+
relationship.data.map((d) => deserializeFunction(d))
496+
);
497+
498+
if (included) {
499+
set(
500+
deserializedData,
501+
relationshipKey,
502+
relationship.data.map((d) =>
503+
this.deserializeIncluded(d.type, d.id, relationshipOptions, included)
504+
)
505+
);
506+
}
507+
} else {
508+
set(
509+
deserializedData,
510+
relationshipKey,
511+
relationship.data.map((d) =>
512+
included
513+
? this.deserializeIncluded(d.type, d.id, relationshipOptions, included)
514+
: deserializeFunction(d)
515+
)
516+
);
517+
}
518+
} else if (relationship.data === null) {
519+
// null data
500520
set(
501521
deserializedData,
502-
relationshipKey,
503-
relationship.data.map((d) =>
504-
included
505-
? this.deserializeIncluded(
506-
d.type,
507-
d.id,
508-
options.relationships[relationshipKey],
509-
included
510-
)
511-
: deserializeFunction(d)
512-
)
522+
(relationshipOptions && relationshipOptions.alternativeKey) || relationshipKey,
523+
null
513524
);
514-
} else if (relationship.data === null) {
515-
// null data
516-
set(deserializedData, relationshipKey, null);
525+
} else if (relationshipOptions && relationshipOptions.alternativeKey) {
526+
set(
527+
deserializedData,
528+
relationshipOptions.alternativeKey,
529+
deserializeFunction(relationship.data)
530+
);
531+
532+
if (included) {
533+
set(
534+
deserializedData,
535+
relationshipKey,
536+
this.deserializeIncluded(
537+
relationship.data.type,
538+
relationship.data.id,
539+
relationshipOptions,
540+
included
541+
)
542+
);
543+
}
517544
} else {
518545
set(
519546
deserializedData,
@@ -522,7 +549,7 @@ module.exports = class JSONAPISerializer {
522549
? this.deserializeIncluded(
523550
relationship.data.type,
524551
relationship.data.id,
525-
options.relationships[relationshipKey],
552+
relationshipOptions,
526553
included
527554
)
528555
: deserializeFunction(relationship.data)

test/unit/JSONAPISerializer.test.js

Lines changed: 158 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1631,9 +1631,9 @@ describe('JSONAPISerializer', function() {
16311631
done();
16321632
});
16331633

1634-
it('should deserialize with \'alternativeKey\' option', function(done) {
1634+
it('should deserialize with \'alternativeKey\' option and no included', function(done) {
16351635
const Serializer = new JSONAPISerializer();
1636-
Serializer.register('articles', {
1636+
Serializer.register('article', {
16371637
relationships: {
16381638
author: {
16391639
type: 'people',
@@ -1642,6 +1642,8 @@ describe('JSONAPISerializer', function() {
16421642
}
16431643
});
16441644

1645+
Serializer.register('people', {});
1646+
16451647
const data = {
16461648
data: {
16471649
type: 'article',
@@ -1662,9 +1664,160 @@ describe('JSONAPISerializer', function() {
16621664
}
16631665
};
16641666

1665-
const deserializedData = Serializer.deserialize('articles', data);
1666-
expect(deserializedData).to.have.property('author_id');
1667-
expect(deserializedData).to.not.property('author');
1667+
const deserializedData = Serializer.deserialize('article', data);
1668+
expect(deserializedData).to.have.property('author_id').to.eql('1');
1669+
expect(deserializedData).to.not.have.property('author');
1670+
done();
1671+
});
1672+
1673+
it('should deserialize with \'alternativeKey\' option and included', function(done) {
1674+
const Serializer = new JSONAPISerializer();
1675+
Serializer.register('article', {
1676+
relationships: {
1677+
author: {
1678+
type: 'people',
1679+
alternativeKey: 'author_id'
1680+
}
1681+
}
1682+
});
1683+
1684+
Serializer.register('people', {});
1685+
1686+
const data = {
1687+
data: {
1688+
type: 'article',
1689+
id: '1',
1690+
attributes: {
1691+
title: 'JSON API paints my bikeshed!',
1692+
body: 'The shortest article. Ever.',
1693+
created: '2015-05-22T14:56:29.000Z'
1694+
},
1695+
relationships: {
1696+
author: {
1697+
data: {
1698+
type: 'people',
1699+
id: '1'
1700+
}
1701+
}
1702+
}
1703+
},
1704+
included: [
1705+
{
1706+
type: 'people',
1707+
id: '1',
1708+
attributes: {
1709+
firstName: 'Kaley',
1710+
lastName: 'Maggio',
1711+
}
1712+
}
1713+
]
1714+
};
1715+
1716+
const deserializedData = Serializer.deserialize('article', data);
1717+
expect(deserializedData).to.have.property('author_id').to.eql('1');
1718+
expect(deserializedData).to.have.property('author').to.deep.equal({id: '1', firstName: 'Kaley', lastName: 'Maggio'});
1719+
done();
1720+
});
1721+
1722+
it('should deserialize with a relationship array and \'alternativeKey\' option and no included', function(done) {
1723+
const Serializer = new JSONAPISerializer();
1724+
Serializer.register('article', {
1725+
relationships: {
1726+
author: {
1727+
type: 'people',
1728+
alternativeKey: 'author_id'
1729+
}
1730+
}
1731+
});
1732+
1733+
Serializer.register('people', {});
1734+
1735+
const data = {
1736+
data: {
1737+
type: 'article',
1738+
id: '1',
1739+
attributes: {
1740+
title: 'JSON API paints my bikeshed!',
1741+
body: 'The shortest article. Ever.',
1742+
created: '2015-05-22T14:56:29.000Z'
1743+
},
1744+
relationships: {
1745+
author: {
1746+
data: [{
1747+
type: 'people',
1748+
id: '1'
1749+
}, {
1750+
type: 'people',
1751+
id: '2'
1752+
}]
1753+
}
1754+
}
1755+
}
1756+
};
1757+
1758+
const deserializedData = Serializer.deserialize('article', data);
1759+
expect(deserializedData).to.have.property('author_id').to.eql(['1', '2']);
1760+
expect(deserializedData).to.not.have.property('author');
1761+
done();
1762+
});
1763+
1764+
it('should deserialize with a relationship array \'alternativeKey\' option and included', function(done) {
1765+
const Serializer = new JSONAPISerializer();
1766+
Serializer.register('article', {
1767+
relationships: {
1768+
author: {
1769+
type: 'people',
1770+
alternativeKey: 'author_id'
1771+
}
1772+
}
1773+
});
1774+
1775+
Serializer.register('people', {});
1776+
1777+
const data = {
1778+
data: {
1779+
type: 'article',
1780+
id: '1',
1781+
attributes: {
1782+
title: 'JSON API paints my bikeshed!',
1783+
body: 'The shortest article. Ever.',
1784+
created: '2015-05-22T14:56:29.000Z'
1785+
},
1786+
relationships: {
1787+
author: {
1788+
data: [{
1789+
type: 'people',
1790+
id: '1'
1791+
}, {
1792+
type: 'people',
1793+
id: '2'
1794+
}]
1795+
}
1796+
}
1797+
},
1798+
included: [
1799+
{
1800+
type: 'people',
1801+
id: '1',
1802+
attributes: {
1803+
firstName: 'Kaley',
1804+
lastName: 'Maggio',
1805+
}
1806+
},
1807+
{
1808+
type: 'people',
1809+
id: '2',
1810+
attributes: {
1811+
firstName: 'Clarence',
1812+
lastName: 'Davis',
1813+
}
1814+
}
1815+
]
1816+
};
1817+
1818+
const deserializedData = Serializer.deserialize('article', data);
1819+
expect(deserializedData).to.have.property('author_id').to.eql(['1', '2']);
1820+
expect(deserializedData).to.have.property('author').to.deep.equal([{id: '1', firstName: 'Kaley', lastName: 'Maggio'}, {id: '2', firstName: 'Clarence', lastName: 'Davis'}]);
16681821
done();
16691822
});
16701823

0 commit comments

Comments
 (0)