diff --git a/lib/scope.js b/lib/scope.js index 98c1ea3dc..5b2127c01 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -431,11 +431,16 @@ function defineScope(cls, targetClass, name, params, methods, options) { options = {}; } options = options || {}; + const targetModel = definition.targetModel(this._receiver); // If there is a through model // run another query to apply filter on relatedModel(targetModel) // see github.com/strongloop/loopback-datasource-juggler/issues/1795 let scopeOnRelatedModel = false; let queryRelated; + let keyFrom; + let relatedModel; + let IdKey; + let fieldsRelated; if (this._scope && this._scope.collect && where !== null && typeof where === 'object') { queryRelated = { @@ -446,24 +451,23 @@ function defineScope(cls, targetClass, name, params, methods, options) { }; where = {}; scopeOnRelatedModel = true; + relatedModel = targetModel.relations[queryRelated.relation].modelTo; + IdKey = idName(relatedModel); + keyFrom = targetModel.relations[queryRelated.relation].keyFrom || IdKey; + fieldsRelated = [keyFrom]; } - const targetModel = definition.targetModel(this._receiver); const scoped = (this._scope && this._scope.where) || {}; - const filter = mergeQuery({where: scoped}, {where: where || {}}); + const filter = mergeQuery({where: scoped}, {where: where || {}, fields: fieldsRelated}); if (!scopeOnRelatedModel) { return targetModel.destroyAll(filter.where, options, cb); } return targetModel.find(filter, options, function(err, findData) { - const relatedModel = targetModel.relations[queryRelated.relation].modelTo; - const keyFrom = targetModel.relations[queryRelated.relation].keyFrom; - const IdKey = idName(relatedModel); - // Merge queryRelated filter and targetId filter const buildWhere = function() { return { and: [ { - [IdKey]: collectTargetIds(findData, keyFrom || IdKey), + [IdKey]: collectTargetIds(findData, keyFrom), }, queryRelated.scope.where], }; @@ -472,7 +476,7 @@ function defineScope(cls, targetClass, name, params, methods, options) { queryRelated.scope.where = buildWhere(); } else { queryRelated.scope.where = {}; - queryRelated.scope.where[IdKey] = collectTargetIds(findData, keyFrom || IdKey); + queryRelated.scope.where[IdKey] = collectTargetIds(findData, keyFrom); } return relatedModel.destroyAll(queryRelated.scope.where, options, cb); }); @@ -492,11 +496,16 @@ function defineScope(cls, targetClass, name, params, methods, options) { options = {}; } options = options || {}; + const targetModel = definition.targetModel(this._receiver); // If there is a through model // run another query to apply filter on relatedModel(targetModel) // see github.com/strongloop/loopback-datasource-juggler/issues/1795 let scopeOnRelatedModel = false; let queryRelated; + let keyFrom; + let relatedModel; + let IdKey; + let fieldsRelated; if (this._scope && this._scope.collect && where !== null && typeof where === 'object') { queryRelated = { @@ -507,24 +516,23 @@ function defineScope(cls, targetClass, name, params, methods, options) { }; where = {}; scopeOnRelatedModel = true; + relatedModel = targetModel.relations[queryRelated.relation].modelTo; + IdKey = idName(relatedModel); + keyFrom = targetModel.relations[queryRelated.relation].keyFrom || IdKey; + fieldsRelated = [keyFrom]; } - const targetModel = definition.targetModel(this._receiver); const scoped = (this._scope && this._scope.where) || {}; - const filter = mergeQuery({where: scoped}, {where: where || {}}); + const filter = mergeQuery({where: scoped}, {where: where || {}, fields: fieldsRelated}); if (!scopeOnRelatedModel) { return targetModel.updateAll(filter.where, data, options, cb); } return targetModel.find(filter, options, function(err, findData) { - const relatedModel = targetModel.relations[queryRelated.relation].modelTo; - const keyFrom = targetModel.relations[queryRelated.relation].keyFrom; - const IdKey = idName(relatedModel); - // Merge queryRelated filter and targetId filter const buildWhere = function() { return { and: [ { - [IdKey]: collectTargetIds(findData, keyFrom || IdKey), + [IdKey]: collectTargetIds(findData, keyFrom), }, queryRelated.scope.where], }; @@ -533,7 +541,7 @@ function defineScope(cls, targetClass, name, params, methods, options) { queryRelated.scope.where = buildWhere(); } else { queryRelated.scope.where = {}; - queryRelated.scope.where[IdKey] = collectTargetIds(findData, keyFrom || IdKey); + queryRelated.scope.where[IdKey] = collectTargetIds(findData, keyFrom); } return relatedModel.updateAll(queryRelated.scope.where, data, options, cb); }); @@ -581,37 +589,41 @@ function defineScope(cls, targetClass, name, params, methods, options) { options = {}; } options = options || {}; + const targetModel = definition.targetModel(this._receiver); // If there is a through model // run another query to apply filter on relatedModel(targetModel) // see github.com/strongloop/loopback-datasource-juggler/issues/1795 let scopeOnRelatedModel = false; let queryRelated; + let keyFrom; + let relatedModel; + let IdKey; if (this._scope && this._scope.collect && filter && filter.where !== null && typeof filter.where === 'object') { queryRelated = { relation: this._scope.collect, scope: filter, }; - filter = {}; scopeOnRelatedModel = true; + relatedModel = targetModel.relations[queryRelated.relation].modelTo; + IdKey = idName(relatedModel); + keyFrom = targetModel.relations[queryRelated.relation].keyFrom || IdKey; + filter = { + fields: [keyFrom], + }; } - const targetModel = definition.targetModel(this._receiver); const scoped = (this._scope && this._scope.where) || {}; filter = mergeQuery({where: scoped}, filter || {}); if (!scopeOnRelatedModel) { return targetModel.findOne(filter, options, cb); } return targetModel.find(filter, options, function(err, data) { - const relatedModel = targetModel.relations[queryRelated.relation].modelTo; - const keyFrom = targetModel.relations[queryRelated.relation].keyFrom; - const IdKey = idName(relatedModel); - // Merge queryRelated filter and targetId filter const buildWhere = function() { return { and: [ { - [IdKey]: collectTargetIds(data, keyFrom || IdKey), + [IdKey]: collectTargetIds(data, keyFrom), }, queryRelated.scope.where], }; @@ -620,7 +632,7 @@ function defineScope(cls, targetClass, name, params, methods, options) { queryRelated.scope.where = buildWhere(); } else { queryRelated.scope.where = {}; - queryRelated.scope.where[IdKey] = collectTargetIds(data, keyFrom || IdKey); + queryRelated.scope.where[IdKey] = collectTargetIds(data, keyFrom); } return relatedModel.findOne(queryRelated.scope, options, cb); }); @@ -637,11 +649,16 @@ function defineScope(cls, targetClass, name, params, methods, options) { options = {}; } options = options || {}; + const targetModel = definition.targetModel(this._receiver); // If there is a through model // run another query to apply filter on relatedModel(targetModel) // see github.com/strongloop/loopback-datasource-juggler/issues/1795 let scopeOnRelatedModel = false; let queryRelated; + let keyFrom; + let relatedModel; + let IdKey; + let fieldsRelated; if (this._scope && this._scope.collect && where !== null && typeof where === 'object') { queryRelated = { @@ -652,24 +669,23 @@ function defineScope(cls, targetClass, name, params, methods, options) { }; where = {}; scopeOnRelatedModel = true; + relatedModel = targetModel.relations[queryRelated.relation].modelTo; + IdKey = idName(relatedModel); + keyFrom = targetModel.relations[queryRelated.relation].keyFrom || IdKey; + fieldsRelated = [keyFrom]; } - const targetModel = definition.targetModel(this._receiver); const scoped = (this._scope && this._scope.where) || {}; - const filter = mergeQuery({where: scoped}, {where: where || {}}); + const filter = mergeQuery({where: scoped}, {where: where || {}, fields: fieldsRelated}); if (!scopeOnRelatedModel) { return targetModel.count(filter.where, options, cb); } return targetModel.find(filter, options, function(err, data) { - const relatedModel = targetModel.relations[queryRelated.relation].modelTo; - const keyFrom = targetModel.relations[queryRelated.relation].keyFrom; - const IdKey = idName(relatedModel); - // Merge queryRelated filter and targetId filter const buildWhere = function() { return { and: [ { - [IdKey]: collectTargetIds(data, keyFrom || IdKey), + [IdKey]: collectTargetIds(data, keyFrom), }, queryRelated.scope.where], }; @@ -678,7 +694,7 @@ function defineScope(cls, targetClass, name, params, methods, options) { queryRelated.scope.where = buildWhere(); } else { queryRelated.scope.where = {}; - queryRelated.scope.where[IdKey] = collectTargetIds(data, keyFrom || IdKey); + queryRelated.scope.where[IdKey] = collectTargetIds(data, keyFrom); } return relatedModel.count(queryRelated.scope.where, options, cb); });