Fix query for related models (#1522)
This commit is contained in:
parent
994ec98b48
commit
7a4c6ca2f9
46
lib/scope.js
46
lib/scope.js
|
@ -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);
|
||||||
|
|
|
@ -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\'' +
|
||||||
|
|
Loading…
Reference in New Issue