Merge pull request #66 from strongloop/feature/fix-through
Fix a regression caused by 'include' changes
This commit is contained in:
commit
349205ce69
32
lib/dao.js
32
lib/dao.js
|
@ -543,21 +543,31 @@ DataAccessObject.find = function find(params, cb) {
|
|||
obj._initProperties(d, false, params.fields);
|
||||
|
||||
if (params && params.include) {
|
||||
// Try to normalize the include
|
||||
var includes = params.include;
|
||||
if(typeof includes === 'string') {
|
||||
includes = [includes];
|
||||
} else if(typeof includes === 'object') {
|
||||
includes = Object.keys(includes);
|
||||
if (params.collect) {
|
||||
// The collect property indicates that the query is to return the
|
||||
// standlone items for a related model, not as child of the parent object
|
||||
// For example, article.tags
|
||||
obj = obj.__cachedRelations[params.collect];
|
||||
} else {
|
||||
// This handles the case to return parent items including the related
|
||||
// models. For example, Article.find({include: 'tags'}, ...);
|
||||
// Try to normalize the include
|
||||
var includes = params.include || [];
|
||||
if (typeof includes === 'string') {
|
||||
includes = [includes];
|
||||
} else if (typeof includes === 'object') {
|
||||
includes = Object.keys(includes);
|
||||
}
|
||||
includes.forEach(function (inc) {
|
||||
// Promote the included model as a direct property
|
||||
obj.__data[inc] = obj.__cachedRelations[inc];
|
||||
});
|
||||
delete obj.__data.__cachedRelations;
|
||||
}
|
||||
includes.forEach(function (inc) {
|
||||
// Promote the included model as a direct property
|
||||
obj.__data[inc] = obj.__cachedRelations[inc];
|
||||
});
|
||||
delete obj.__data.__cachedRelations;
|
||||
}
|
||||
data[i] = obj;
|
||||
});
|
||||
|
||||
if (data && data.countBeforeLimit) {
|
||||
data.countBeforeLimit = data.countBeforeLimit;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,18 @@ Relation.relationNameFor = function relationNameFor(foreignKey) {
|
|||
}
|
||||
};
|
||||
|
||||
function lookupModel(models, modelName) {
|
||||
if(models[modelName]) {
|
||||
return models[modelName];
|
||||
}
|
||||
var lookupClassName = modelName.toLowerCase();
|
||||
for (var name in models) {
|
||||
if (name.toLowerCase() === lookupClassName) {
|
||||
return models[name];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare hasMany relation
|
||||
*
|
||||
|
@ -34,11 +46,7 @@ Relation.hasMany = function hasMany(anotherClass, params) {
|
|||
anotherClass = params.model;
|
||||
} else {
|
||||
var anotherClassName = i8n.singularize(anotherClass).toLowerCase();
|
||||
for (var name in this.dataSource.modelBuilder.models) {
|
||||
if (name.toLowerCase() === anotherClassName) {
|
||||
anotherClass = this.dataSource.modelBuilder.models[name];
|
||||
}
|
||||
}
|
||||
anotherClass = lookupModel(this.dataSource.modelBuilder.models, anotherClassName);
|
||||
}
|
||||
}
|
||||
var methodName = params.as || i8n.camelize(anotherClass.pluralModelName, true);
|
||||
|
@ -130,9 +138,13 @@ Relation.hasMany = function hasMany(anotherClass, params) {
|
|||
|
||||
function find(id, cb) {
|
||||
anotherClass.findById(id, function (err, inst) {
|
||||
if (err) return cb(err);
|
||||
if (!inst) return cb(new Error('Not found'));
|
||||
if (inst[fk] && inst[fk].toString() == this[idName].toString()) {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
if (!inst) {
|
||||
return cb(new Error('Not found'));
|
||||
}
|
||||
if (inst[fk] && inst[fk].toString() === this[idName].toString()) {
|
||||
cb(null, inst);
|
||||
} else {
|
||||
cb(new Error('Permission denied'));
|
||||
|
@ -143,9 +155,13 @@ Relation.hasMany = function hasMany(anotherClass, params) {
|
|||
function destroy(id, cb) {
|
||||
var self = this;
|
||||
anotherClass.findById(id, function (err, inst) {
|
||||
if (err) return cb(err);
|
||||
if (!inst) return cb(new Error('Not found'));
|
||||
if (inst[fk] && inst[fk].toString() == self[idName].toString()) {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
if (!inst) {
|
||||
return cb(new Error('Not found'));
|
||||
}
|
||||
if (inst[fk] && inst[fk].toString() === self[idName].toString()) {
|
||||
inst.destroy(cb);
|
||||
} else {
|
||||
cb(new Error('Permission denied'));
|
||||
|
@ -186,11 +202,7 @@ Relation.belongsTo = function (anotherClass, params) {
|
|||
anotherClass = params.model;
|
||||
} else {
|
||||
var anotherClassName = anotherClass.toLowerCase();
|
||||
for (var name in this.dataSource.modelBuilder.models) {
|
||||
if (name.toLowerCase() === anotherClassName) {
|
||||
anotherClass = this.dataSource.modelBuilder.models[name];
|
||||
}
|
||||
}
|
||||
anotherClass = lookupModel(this.dataSource.modelBuilder.models, anotherClassName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,16 +219,20 @@ Relation.belongsTo = function (anotherClass, params) {
|
|||
};
|
||||
|
||||
this.dataSource.defineForeignKey(this.modelName, fk, anotherClass.modelName);
|
||||
this.prototype['__finders__'] = this.prototype['__finders__'] || {};
|
||||
this.prototype.__finders__ = this.prototype.__finders__ || {};
|
||||
|
||||
this.prototype['__finders__'][methodName] = function (id, cb) {
|
||||
this.prototype.__finders__[methodName] = function (id, cb) {
|
||||
if (id === null) {
|
||||
cb(null, null);
|
||||
return;
|
||||
}
|
||||
anotherClass.findById(id, function (err, inst) {
|
||||
if (err) return cb(err);
|
||||
if (!inst) return cb(null, null);
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
if (!inst) {
|
||||
return cb(null, null);
|
||||
}
|
||||
if (inst[idName] === this[fk]) {
|
||||
cb(null, inst);
|
||||
} else {
|
||||
|
@ -234,7 +250,7 @@ Relation.belongsTo = function (anotherClass, params) {
|
|||
}
|
||||
var self = this;
|
||||
var cachedValue;
|
||||
if (!refresh && this.__cachedRelations && (typeof this.__cachedRelations[methodName] !== 'undefined')) {
|
||||
if (!refresh && this.__cachedRelations && (this.__cachedRelations[methodName] !== undefined)) {
|
||||
cachedValue = this.__cachedRelations[methodName];
|
||||
}
|
||||
if (p instanceof ModelBaseClass) { // acts as setter
|
||||
|
@ -277,7 +293,7 @@ Relation.hasAndBelongsToMany = function hasAndBelongsToMany(anotherClass, params
|
|||
if (params.model) {
|
||||
anotherClass = params.model;
|
||||
} else {
|
||||
anotherClass = lookupModel(i8n.singularize(anotherClass)) ||
|
||||
anotherClass = lookupModel(models, i8n.singularize(anotherClass).toLowerCase()) ||
|
||||
anotherClass;
|
||||
}
|
||||
if (typeof anotherClass === 'string') {
|
||||
|
@ -288,7 +304,7 @@ Relation.hasAndBelongsToMany = function hasAndBelongsToMany(anotherClass, params
|
|||
if (!params.through) {
|
||||
var name1 = this.modelName + anotherClass.modelName;
|
||||
var name2 = anotherClass.modelName + this.modelName;
|
||||
params.through = lookupModel(name1) || lookupModel(name2) ||
|
||||
params.through = lookupModel(models, name1) || lookupModel(models, name2) ||
|
||||
this.dataSource.define(name1);
|
||||
}
|
||||
params.through.belongsTo(this);
|
||||
|
@ -296,13 +312,4 @@ Relation.hasAndBelongsToMany = function hasAndBelongsToMany(anotherClass, params
|
|||
|
||||
this.hasMany(anotherClass, {as: params.as, through: params.through});
|
||||
|
||||
function lookupModel(modelName) {
|
||||
var lookupClassName = modelName.toLowerCase();
|
||||
for (var name in models) {
|
||||
if (name.toLowerCase() === lookupClassName) {
|
||||
return models[name];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue