Skip to content

Commit

Permalink
Merge branch 'ryanxwelch-remove_duplicate_includes'
Browse files Browse the repository at this point in the history
  • Loading branch information
digitalsadhu committed Jun 11, 2017
2 parents 6f71beb + 4152a3a commit 78c91a8
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 1 deletion.
20 changes: 19 additions & 1 deletion lib/serializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,25 @@ function handleIncludes (resp, includes, relations, app) {
})

if (embedded.length) {
resp.included = _.flattenDeep(embedded)
// This array may contain duplicate models if the same item is referenced multiple times in 'data'
var duplicate = _.flattenDeep(embedded)
// So begin with an empty array that will only contain unique items
var unique = []
// Iterate through each item in the first array
duplicate.forEach(function (d) {
// Count the number of items in the unique array with matching 'type' AND 'id'
// Since we're adhering to the JSONAPI spec, both 'type' and 'id' can assumed to be present
// Both 'type' and 'id' are needed for comparison because we could theoretically have objects of different
// types who happen to have the same 'id', and those would not be considered duplicates
var count = unique.filter(function (u) {
return (u.type === d.type) && (u.id === d.id)
}).length
// If there are no matching entries, then add the item to the unique array
if (count === 0) {
unique.push(d)
}
})
resp.included = unique
}
}

Expand Down
25 changes: 25 additions & 0 deletions test/hasManyRelationships.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,29 @@ describe('loopback json api hasMany relationships', function () {
})
})
})

describe('Duplicate models in `includes`', function () {
beforeEach(function () {
const Foo = ds.createModel('foo', {title: String})
app.model(Foo)
const Bar = ds.createModel('bar', {title: String})
app.model(Bar)
Foo.hasMany(Bar)
Foo.belongsTo(Bar)

return Promise.all([
Foo.create({title: 'one', barId: 1}),
Bar.create({title: 'one', barId: 1, fooId: 1})
])
})

it('should not occur', function () {
return request(app).get('/foos/1/?include=bars,bar')
.expect(200)
.then(function (res) {
expect(res.body.included.length).to.equal(1,
'Should be exactly 1 item in included array')
})
})
})
})

0 comments on commit 78c91a8

Please sign in to comment.