Skip to content

Commit ae2dafb

Browse files
authored
Merge pull request #234 from rocknrolla777/relationships-in-include
Relationships in include
2 parents d2130d7 + 4f63728 commit ae2dafb

File tree

4 files changed

+85
-8
lines changed

4 files changed

+85
-8
lines changed

lib/serializer.js

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ function defaultSerialize (options, cb) {
4242
resultData,
4343
options.requestedIncludes,
4444
options.relationships,
45-
options.app
45+
options
4646
)
4747
} catch (err) {
4848
cb(err)
@@ -344,7 +344,11 @@ function makeLinks (links, item) {
344344
* @throws {Error}
345345
* @return {undefined}
346346
*/
347-
function handleIncludes (resp, includes, relations, app) {
347+
function handleIncludes (resp, includes, relations, options) {
348+
var app = options.app
349+
350+
relations = utils.setIncludedRelations(relations, app)
351+
348352
var resources = _.isArray(resp.data) ? resp.data : [resp.data]
349353

350354
if (typeof includes === 'string') {
@@ -360,6 +364,7 @@ function handleIncludes (resp, includes, relations, app) {
360364
var embedded = resources.map(function subsituteEmbeddedForIds (resource) {
361365
return includes.map(function (include) {
362366
var relation = relations[include]
367+
var includedRelations = relations[include].relations
363368
var propertyKey = relation.keyFrom
364369
var plural = ''
365370
if (relation.polymorphic && utils.relationFkOnModelFrom(relation)) {
@@ -392,7 +397,9 @@ function handleIncludes (resp, includes, relations, app) {
392397
rel,
393398
propertyKey,
394399
relation.keyTo,
395-
plural
400+
plural,
401+
includedRelations,
402+
options
396403
)
397404
})
398405
embeds = _.compact(embeds)
@@ -410,7 +417,9 @@ function handleIncludes (resp, includes, relations, app) {
410417
rel,
411418
propertyKey,
412419
relation.keyFrom,
413-
plural
420+
plural,
421+
includedRelations,
422+
options
414423
)
415424

416425
resource.relationships[include].data = {
@@ -456,12 +465,24 @@ function handleIncludes (resp, includes, relations, app) {
456465
* @memberOf {Serializer}
457466
* @param {Object} relationship
458467
* @param {String} key
468+
* @param {String} fk
459469
* @param {String} type
470+
* @param {Object} includedRelations
471+
* @param {Object} options
460472
* @return {Object}
461473
*/
462-
function createCompoundIncludes (relationship, key, fk, type) {
474+
function createCompoundIncludes (relationship, key, fk, type, includedRelations, options) {
463475
var compoundInclude = makeRelation(type, String(relationship[key]))
464476

477+
if (options && !_.isEmpty(includedRelations)) {
478+
var defaultModelPath = options.modelPath
479+
options.modelPath = type
480+
481+
compoundInclude.relationships = parseRelations(relationship, includedRelations, options)
482+
483+
options.modelPath = defaultModelPath
484+
}
485+
465486
// remove the id key since its part of the base compound document, not part of attributes
466487
delete relationship[key]
467488
delete relationship[fk]

lib/utils.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ module.exports = {
1818
primaryKeyForModel: primaryKeyForModel,
1919
shouldNotApplyJsonApi: shouldNotApplyJsonApi,
2020
shouldApplyJsonApi: shouldApplyJsonApi,
21-
relationFkOnModelFrom: relationFkOnModelFrom
21+
relationFkOnModelFrom: relationFkOnModelFrom,
22+
setIncludedRelations: setIncludedRelations
2223
}
2324

2425
function primaryKeyForModel (model) {
@@ -227,3 +228,13 @@ function shouldNotApplyJsonApi (ctx, options) {
227228
function relationFkOnModelFrom (relation) {
228229
return relation.type === 'belongsTo' || relation.type === 'referencesMany'
229230
}
231+
232+
function setIncludedRelations (relations, app) {
233+
for (var key in relations) {
234+
if (relations.hasOwnProperty(key)) {
235+
var name = (relations[key].modelTo && relations[key].modelTo.sharedClass.name) || relations[key].name
236+
relations[key].relations = app.models[name] && app.models[name].relations
237+
}
238+
}
239+
return relations
240+
}

test/hasMany.test.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,8 @@ describe('loopback json api hasMany relationships', function () {
242242
expect(res.body.included[0]).to.have.all.keys(
243243
'type',
244244
'id',
245-
'attributes'
245+
'attributes',
246+
'relationships'
246247
)
247248
expect(res.body.included[0].type).to.equal('comments')
248249
expect(res.body.included[0].id).to.equal('1')
@@ -275,6 +276,13 @@ describe('loopback json api hasMany relationships', function () {
275276
attributes: {
276277
title: 'My comment',
277278
comment: 'My comment text'
279+
},
280+
relationships: {
281+
replies: {
282+
links: {
283+
related: res.body.included[0].relationships.replies.links.related
284+
}
285+
}
278286
}
279287
})
280288
expect(res.body.included[1]).to.deep.equal({
@@ -283,6 +291,13 @@ describe('loopback json api hasMany relationships', function () {
283291
attributes: {
284292
title: 'My second comment',
285293
comment: 'My second comment text'
294+
},
295+
relationships: {
296+
replies: {
297+
links: {
298+
related: res.body.included[1].relationships.replies.links.related
299+
}
300+
}
286301
}
287302
})
288303
done()
@@ -368,7 +383,8 @@ describe('loopback json api hasMany relationships', function () {
368383
expect(res.body.included[0]).to.have.all.keys(
369384
'type',
370385
'id',
371-
'attributes'
386+
'attributes',
387+
'relationships'
372388
)
373389
expect(res.body.included[0].type).to.equal('comments')
374390
expect(res.body.included[0].id).to.equal('1')

test/hasManyRelationships.test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,13 @@ describe('loopback json api hasMany relationships', function () {
104104
attributes: {
105105
firstName: 'Joe',
106106
lastName: 'Shmoe'
107+
},
108+
relationships: {
109+
posts: {
110+
links: {
111+
related: res.body.included[0].relationships.posts.links.related
112+
}
113+
}
107114
}
108115
})
109116
expect(res.body.included[1]).to.deep.equal({
@@ -112,6 +119,17 @@ describe('loopback json api hasMany relationships', function () {
112119
attributes: {
113120
title: 'My comment',
114121
comment: 'My comment text'
122+
},
123+
relationships: {
124+
post: {
125+
data: {
126+
id: 1,
127+
type: 'posts'
128+
},
129+
links: {
130+
related: res.body.included[1].relationships.post.links.related
131+
}
132+
}
115133
}
116134
})
117135
expect(res.body.included[2]).to.deep.equal({
@@ -120,6 +138,17 @@ describe('loopback json api hasMany relationships', function () {
120138
attributes: {
121139
title: 'My second comment',
122140
comment: 'My second comment text'
141+
},
142+
relationships: {
143+
post: {
144+
data: {
145+
id: 1,
146+
type: 'posts'
147+
},
148+
links: {
149+
related: res.body.included[2].relationships.post.links.related
150+
}
151+
}
123152
}
124153
})
125154
done()

0 commit comments

Comments
 (0)