Merge pull request #329 from fabien/feature/include-scope

Enable include scope for belongsTo
This commit is contained in:
Fabien Franzen 2014-10-15 18:08:42 +02:00
commit 5662d9f0c2
3 changed files with 62 additions and 27 deletions

View File

@ -167,7 +167,7 @@ Inclusion.include = function (objects, include, cb) {
var related; // relation accessor function
if (relation.multiple && scope) {
if ((relation.multiple || relation.type === 'belongsTo') && scope) {
var includeScope = {};
var filter = scope.conditions();
@ -183,6 +183,7 @@ Inclusion.include = function (objects, include, cb) {
}
utils.mergeQuery(filter, includeScope, {fields: false});
related = inst[relationName].bind(inst, filter);
} else {
related = inst[relationName].bind(inst);

View File

@ -1250,10 +1250,14 @@ BelongsTo.prototype.related = function (refresh, params) {
var fk = this.definition.keyFrom;
var modelInstance = this.modelInstance;
var discriminator;
var scopeQuery = null;
if (arguments.length === 1) {
params = refresh;
refresh = false;
} else if (arguments.length === 2
&& typeof refresh === 'object' && typeof params === 'function') {
scopeQuery = refresh;
} else if (arguments.length > 2) {
throw new Error('Method can\'t be called with more than two arguments');
}
@ -1303,6 +1307,12 @@ BelongsTo.prototype.related = function (refresh, params) {
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) {
if (err) {
return cb(err);

View File

@ -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({
include: {relation: 'posts', scope:{
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({
include: {relation: 'passports', scope:{
where: { number: '2' }
@ -253,37 +270,44 @@ describe('include', function () {
});
it('should support hasAndBelongsToMany', function (done) {
Assembly.destroyAll(function(err) {
Part.destroyAll(function(err) {
Assembly.relations.parts.modelThrough.destroyAll(function(err) {
Assembly.create({name: 'car'}, function (err, assembly) {
Part.create({partNumber: 'engine'}, function (err, part) {
assembly.parts.add(part, function (err, data) {
assembly.parts(function (err, parts) {
should.not.exist(err);
should.exists(parts);
parts.length.should.equal(1);
parts[0].partNumber.should.equal('engine');
// Create a part
assembly.parts.create({partNumber: 'door'}, function (err, part4) {
Assembly.find({include: 'parts'}, function (err, assemblies) {
assemblies.length.should.equal(1);
assemblies[0].parts.length.should.equal(2);
done();
});
});
Assembly.create({name: 'car'}, function (err, assembly) {
Part.create({partNumber: 'engine'}, function (err, part) {
assembly.parts.add(part, function (err, data) {
assembly.parts(function (err, parts) {
should.not.exist(err);
should.exists(parts);
parts.length.should.equal(1);
parts[0].partNumber.should.equal('engine');
// Create a part
assembly.parts.create({partNumber: 'door'}, function (err, part4) {
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();
// });
// });
});