Merge branch 'release/2.10.1' into production
This commit is contained in:
commit
4a339522e3
|
@ -167,7 +167,7 @@ Inclusion.include = function (objects, include, cb) {
|
||||||
|
|
||||||
var related; // relation accessor function
|
var related; // relation accessor function
|
||||||
|
|
||||||
if (relation.multiple && scope) {
|
if ((relation.multiple || relation.type === 'belongsTo') && scope) {
|
||||||
var includeScope = {};
|
var includeScope = {};
|
||||||
var filter = scope.conditions();
|
var filter = scope.conditions();
|
||||||
|
|
||||||
|
@ -183,6 +183,7 @@ Inclusion.include = function (objects, include, cb) {
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.mergeQuery(filter, includeScope, {fields: false});
|
utils.mergeQuery(filter, includeScope, {fields: false});
|
||||||
|
|
||||||
related = inst[relationName].bind(inst, filter);
|
related = inst[relationName].bind(inst, filter);
|
||||||
} else {
|
} else {
|
||||||
related = inst[relationName].bind(inst);
|
related = inst[relationName].bind(inst);
|
||||||
|
|
|
@ -257,6 +257,17 @@ Relation.prototype.getCache = function () {
|
||||||
return this.modelInstance.__cachedRelations[this.definition.name];
|
return this.modelInstance.__cachedRelations[this.definition.name];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Relation.prototype.callScopeMethod = function(methodName) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
var modelInstance = this.modelInstance;
|
||||||
|
var rel = modelInstance[this.definition.name];
|
||||||
|
if (rel && typeof rel[methodName] === 'function') {
|
||||||
|
return rel[methodName].apply(rel, args);
|
||||||
|
} else {
|
||||||
|
throw new Error('Unknown scope method: ' + methodName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch the related model(s) - this is a helper method to unify access.
|
* Fetch the related model(s) - this is a helper method to unify access.
|
||||||
* @param (Boolean|Object} condOrRefresh refresh or conditions object
|
* @param (Boolean|Object} condOrRefresh refresh or conditions object
|
||||||
|
@ -1239,10 +1250,14 @@ BelongsTo.prototype.related = function (refresh, params) {
|
||||||
var fk = this.definition.keyFrom;
|
var fk = this.definition.keyFrom;
|
||||||
var modelInstance = this.modelInstance;
|
var modelInstance = this.modelInstance;
|
||||||
var discriminator;
|
var discriminator;
|
||||||
|
var scopeQuery = null;
|
||||||
|
|
||||||
if (arguments.length === 1) {
|
if (arguments.length === 1) {
|
||||||
params = refresh;
|
params = refresh;
|
||||||
refresh = false;
|
refresh = false;
|
||||||
|
} else if (arguments.length === 2
|
||||||
|
&& typeof refresh === 'object' && typeof params === 'function') {
|
||||||
|
scopeQuery = refresh;
|
||||||
} else if (arguments.length > 2) {
|
} else if (arguments.length > 2) {
|
||||||
throw new Error('Method can\'t be called with more than two arguments');
|
throw new Error('Method can\'t be called with more than two arguments');
|
||||||
}
|
}
|
||||||
|
@ -1292,6 +1307,12 @@ BelongsTo.prototype.related = function (refresh, params) {
|
||||||
|
|
||||||
this.definition.applyScope(modelInstance, query);
|
this.definition.applyScope(modelInstance, query);
|
||||||
|
|
||||||
|
if (scopeQuery) mergeQuery(query, scopeQuery);
|
||||||
|
|
||||||
|
if (Array.isArray(query.fields) && query.fields.indexOf(pk) === -1) {
|
||||||
|
query.fields.push(pk); // always include the pk
|
||||||
|
}
|
||||||
|
|
||||||
modelTo.findOne(query, function (err, inst) {
|
modelTo.findOne(query, function (err, inst) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
|
@ -1782,7 +1803,7 @@ EmbedsOne.prototype.create = function (targetModelData, cb) {
|
||||||
|
|
||||||
targetModelData = targetModelData || {};
|
targetModelData = targetModelData || {};
|
||||||
|
|
||||||
var inst = this.build(targetModelData);
|
var inst = this.callScopeMethod('build', targetModelData);
|
||||||
|
|
||||||
var updateEmbedded = function() {
|
var updateEmbedded = function() {
|
||||||
modelInstance.updateAttribute(propertyName,
|
modelInstance.updateAttribute(propertyName,
|
||||||
|
@ -1854,9 +1875,9 @@ EmbedsOne.prototype.update = function (targetModelData, cb) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (!embeddedInstance && cb) {
|
} else if (!embeddedInstance && cb) {
|
||||||
this.create(data, db);
|
this.callScopeMethod('create', data, cb);
|
||||||
} else if (!embeddedInstance) {
|
} else if (!embeddedInstance) {
|
||||||
this.build(data);
|
this.callScopeMethod('build', data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2238,7 +2259,7 @@ EmbedsMany.prototype.create = function (targetModelData, cb) {
|
||||||
|
|
||||||
var embeddedList = this.embeddedList();
|
var embeddedList = this.embeddedList();
|
||||||
|
|
||||||
var inst = this.build(targetModelData);
|
var inst = this.callScopeMethod('build', targetModelData);
|
||||||
|
|
||||||
var updateEmbedded = function() {
|
var updateEmbedded = function() {
|
||||||
modelInstance.updateAttribute(propertyName,
|
modelInstance.updateAttribute(propertyName,
|
||||||
|
@ -2619,7 +2640,7 @@ ReferencesMany.prototype.create = function (targetModelData, cb) {
|
||||||
|
|
||||||
var ids = modelInstance[fk] || [];
|
var ids = modelInstance[fk] || [];
|
||||||
|
|
||||||
var inst = this.build(targetModelData);
|
var inst = this.callScopeMethod('build', targetModelData);
|
||||||
|
|
||||||
inst.save(function(err, inst) {
|
inst.save(function(err, inst) {
|
||||||
if (err) return cb(err, inst);
|
if (err) return cb(err, inst);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "loopback-datasource-juggler",
|
"name": "loopback-datasource-juggler",
|
||||||
"version": "2.10.0",
|
"version": "2.10.1",
|
||||||
"description": "LoopBack DataSoure Juggler",
|
"description": "LoopBack DataSoure Juggler",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"StrongLoop",
|
"StrongLoop",
|
||||||
|
|
|
@ -156,7 +156,24 @@ describe('include', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fetch Users with include scope on Posts', function (done) {
|
it('should fetch Users with include scope on Posts - belongsTo', function (done) {
|
||||||
|
Post.find({
|
||||||
|
include: { relation: 'author', scope:{ fields: ['name'] }}
|
||||||
|
}, function (err, posts) {
|
||||||
|
should.not.exist(err);
|
||||||
|
should.exist(posts);
|
||||||
|
posts.length.should.equal(5);
|
||||||
|
|
||||||
|
var author = posts[0].author();
|
||||||
|
author.name.should.equal('User A');
|
||||||
|
author.should.have.property('id');
|
||||||
|
author.should.not.have.property('age');
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fetch Users with include scope on Posts - hasMany', function (done) {
|
||||||
User.find({
|
User.find({
|
||||||
include: {relation: 'posts', scope:{
|
include: {relation: 'posts', scope:{
|
||||||
order: 'title DESC'
|
order: 'title DESC'
|
||||||
|
@ -186,7 +203,7 @@ describe('include', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fetch Users with include scope on Passports', function (done) {
|
it('should fetch Users with include scope on Passports - hasMany', function (done) {
|
||||||
User.find({
|
User.find({
|
||||||
include: {relation: 'passports', scope:{
|
include: {relation: 'passports', scope:{
|
||||||
where: { number: '2' }
|
where: { number: '2' }
|
||||||
|
@ -253,37 +270,44 @@ describe('include', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support hasAndBelongsToMany', function (done) {
|
it('should support hasAndBelongsToMany', function (done) {
|
||||||
|
Assembly.create({name: 'car'}, function (err, assembly) {
|
||||||
Assembly.destroyAll(function(err) {
|
Part.create({partNumber: 'engine'}, function (err, part) {
|
||||||
Part.destroyAll(function(err) {
|
assembly.parts.add(part, function (err, data) {
|
||||||
Assembly.relations.parts.modelThrough.destroyAll(function(err) {
|
assembly.parts(function (err, parts) {
|
||||||
Assembly.create({name: 'car'}, function (err, assembly) {
|
should.not.exist(err);
|
||||||
Part.create({partNumber: 'engine'}, function (err, part) {
|
should.exists(parts);
|
||||||
assembly.parts.add(part, function (err, data) {
|
parts.length.should.equal(1);
|
||||||
assembly.parts(function (err, parts) {
|
parts[0].partNumber.should.equal('engine');
|
||||||
should.not.exist(err);
|
|
||||||
should.exists(parts);
|
// Create a part
|
||||||
parts.length.should.equal(1);
|
assembly.parts.create({partNumber: 'door'}, function (err, part4) {
|
||||||
parts[0].partNumber.should.equal('engine');
|
|
||||||
|
Assembly.find({include: 'parts'}, function (err, assemblies) {
|
||||||
// Create a part
|
assemblies.length.should.equal(1);
|
||||||
assembly.parts.create({partNumber: 'door'}, function (err, part4) {
|
assemblies[0].parts().length.should.equal(2);
|
||||||
|
done();
|
||||||
Assembly.find({include: 'parts'}, function (err, assemblies) {
|
|
||||||
assemblies.length.should.equal(1);
|
|
||||||
assemblies[0].parts.length.should.equal(2);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Not implemented correctly, see: loopback-datasource-juggler/issues/166
|
||||||
|
//
|
||||||
|
// it('should support include scope on hasAndBelongsToMany', function (done) {
|
||||||
|
// Assembly.find({include: { relation: 'parts', scope: {
|
||||||
|
// where: { partNumber: 'engine' }
|
||||||
|
// }}}, function (err, assemblies) {
|
||||||
|
// assemblies.length.should.equal(1);
|
||||||
|
// var parts = assemblies[0].parts();
|
||||||
|
// parts.should.have.length(1);
|
||||||
|
// parts[0].partNumber.should.equal('engine');
|
||||||
|
// done();
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue