Skip to content

Commit 9fac9b9

Browse files
author
Joel Alejandro Villarreal Bertoldi
authored
Merge pull request #5 from joelalejandro/fix/issue-3-hasmany
Adds support for `hasMany` associations as `included` records
2 parents 4d8f915 + e116df6 commit 9fac9b9

File tree

2 files changed

+30
-10
lines changed

2 files changed

+30
-10
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ app.hooks({
4545

4646
`feathers-hooks-jsonapify` will automatically detect metadata for relationships in the model. It'll create an `included` top-level array in the document when the hook is called via `find`.
4747

48+
> Currently working and tested with `belongsTo` and `hasMany` associations.
49+
4850
#### Example document for a self-referencing model
4951

5052
```json

index.js

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,24 @@ function byPrimaryKey(model) {
4040
* @return {Object}
4141
*/
4242
function createRelationshipObject(include, item) {
43-
const relatedItem = {};
44-
const relatedModelIdAttribute = Object.keys(include.model.attributes).filter(byPrimaryKey(include.model))[0];
45-
const foreignKeyValue = item[include.association.options.foreignKey];
46-
relatedItem.type = include.model.name;
47-
relatedItem[relatedModelIdAttribute] = foreignKeyValue;
48-
return foreignKeyValue !== null ? relatedItem : null;
43+
const relatedModelIdAttribute = include.association.sourceIdentifier; //Object.keys(include.model.attributes).filter(byPrimaryKey(include.model))[0];
44+
const associationValue = item[include.as];
45+
if (Array.isArray(associationValue)) {
46+
const results = [];
47+
associationValue.forEach(function(record) {
48+
const relatedItem = {};
49+
relatedItem.type = include.model.name;
50+
relatedItem[relatedModelIdAttribute] = record[relatedModelIdAttribute];
51+
results.push(relatedItem);
52+
});
53+
return results;
54+
} else if (typeof associationValue === 'object') {
55+
const relatedItem = {};
56+
relatedItem.type = include.model.name;
57+
relatedItem[relatedModelIdAttribute] = associationValue[relatedModelIdAttribute];
58+
return relatedItem;
59+
}
60+
return null;
4961
}
5062

5163
/**
@@ -62,10 +74,16 @@ function parseRelationships(data, includedData) {
6274
relationship[relationshipName] = { data: createRelationshipObject(include, data) };
6375
if (data[include.as] !== null) {
6476
const serializedRelationship = jsonapify(data[include.as], include.model, include.model.name + '/' + data[include.as].id, { include: [] });
65-
includedData.push(Object.assign({}, serializedRelationship.document, { links: serializedRelationship.links }));
66-
delete data[include.as][include.association.options.foreignKey];
77+
if (Array.isArray(serializedRelationship.document)) {
78+
Array.prototype.push.apply(includedData, [...serializedRelationship.document.map(function(item) {
79+
return Object.assign(item, { links: { self: '/' + include.model.name + '/' + item.id }});
80+
})]);
81+
} else {
82+
includedData.push(Object.assign({}, serializedRelationship.document, { links: serializedRelationship.links }));
83+
}
84+
delete data[include.as][include.association.foreignKey];
6785
}
68-
delete data[include.association.options.foreignKey];
86+
delete data[include.association.foreignKey];
6987
delete data[include.as];
7088
if (relationship[relationshipName].data !== null) {
7189
data.relationships = Object.assign({}, data.relationships, relationship);
@@ -125,7 +143,7 @@ function jsonapify(data, model, selfUrl, context) {
125143
attributes: attributes
126144
});
127145

128-
if (json.data.attributes.relationships) {
146+
if (json.data.attributes && json.data.attributes.relationships) {
129147
json.data.relationships = json.data.attributes.relationships;
130148
delete json.data.attributes.relationships;
131149
}

0 commit comments

Comments
 (0)