Fix query for related models (#1522)

This commit is contained in:
Joost de Bruijn 2017-11-14 20:22:48 +01:00 committed by Diana Lau
parent 994ec98b48
commit 7a4c6ca2f9
2 changed files with 46 additions and 23 deletions

View File

@ -116,30 +116,38 @@ ScopeDefinition.prototype.related = function(receiver, scopeParams, condOrRefres
var relatedModel = targetModel.relations[filter.relation].modelTo; var relatedModel = targetModel.relations[filter.relation].modelTo;
var IdKey = idName(relatedModel); var IdKey = idName(relatedModel);
var smartMerge = function(idCond, qWhere, idKey) { // return {inq: [1,2,3]}}
var smartMerge = function(idCollection, qWhere) {
if (!qWhere[IdKey]) return idCollection;
var merged = {}; var merged = {};
var idsA = idCond[idKey].inq;
var idsB = qWhere[idKey].inq ? qWhere[idKey].inq : [qWhere[idKey]]; var idsA = idCollection.inq;
var idsB = qWhere[IdKey].inq ? qWhere[IdKey].inq : [qWhere[IdKey]];
var intersect = _.intersectionWith(idsA, idsB, _.isEqual); var intersect = _.intersectionWith(idsA, idsB, _.isEqual);
if (intersect.length === 1) merged[idKey] = intersect[0]; if (intersect.length === 1) merged = intersect[0];
if (intersect.length > 1) merged[idKey] = {inq: intersect}; if (intersect.length > 1) merged = {inq: intersect};
return merged; return merged;
}; };
// Merge queryRelated filter and targetId filter
var buildWhere = function() {
var IdKeyCondition = {};
IdKeyCondition[IdKey] = collectTargetIds(data, IdKey);
var mergedWhere = smartMerge(IdKeyCondition, queryRelated.where, IdKey);
return mergedWhere;
};
if (queryRelated.where !== undefined) { if (queryRelated.where !== undefined) {
if (!queryRelated.where[IdKey]) { // Merge queryRelated filter and targetId filter
// If it's null, don't bother calling smartMerge or model.find. var IdKeyCondition = {};
// Simply return an empty result to the client. IdKeyCondition[IdKey] = smartMerge(collectTargetIds(data, IdKey),
return cb(null, []); queryRelated.where);
} else {
queryRelated.where = buildWhere(); // if the id in filter doesn't exist after the merge,
} // return empty result
if (_.isObject(IdKeyCondition[IdKey]) && _.isEmpty(IdKeyCondition[IdKey])) return cb(null, []);
var mergedWhere = {
and: [
IdKeyCondition,
_.omit(queryRelated.where, IdKey),
],
};
queryRelated.where = mergedWhere;
} else { } else {
queryRelated.where = {}; queryRelated.where = {};
queryRelated.where[IdKey] = collectTargetIds(data, IdKey); queryRelated.where[IdKey] = collectTargetIds(data, IdKey);

View File

@ -820,12 +820,13 @@ describe('relations', function() {
done(); done();
}); });
}); });
it('returns empty result when filtering with wrong id key', function(done) { it('returns patient where name equal to samplePatient name', function(done) {
var wrongWhereFilter = {where: {wrongIdKey: samplePatientId}}; var whereFilter = {where: {name: 'a'}};
physician.patients(wrongWhereFilter, function(err, ch) { physician.patients(whereFilter, function(err, ch) {
if (err) return done(err); if (err) return done(err);
should.exist(ch); should.exist(ch);
ch.should.have.lengthOf(0); ch.should.have.lengthOf(1);
ch[0].name.should.eql('a');
done(); done();
}); });
}); });
@ -853,6 +854,20 @@ describe('relations', function() {
}); });
}); });
}); });
it('returns empty result when patientId does not belongs to physician', function(done) {
Patient.create({name: 'x'}, function(err, p) {
if (err) return done(err);
should.exist(p);
var wrongWhereFilter = {where: {id: p.id}};
physician.patients(wrongWhereFilter, function(err, ch) {
if (err) return done(err);
should.exist(ch);
ch.should.have.lengthOf(0);
done();
});
});
});
}); });
context('findById with filter include', function() { context('findById with filter include', function() {
it('returns patient where id equal to \'samplePatientId\'' + it('returns patient where id equal to \'samplePatientId\'' +