Merge branch 'master' into fix/refactor-modelto
This commit is contained in:
commit
5a18839053
|
@ -1235,8 +1235,12 @@ var defineScope = require('./scope.js').defineScope;
|
||||||
* @param {ModelClass} [targetClass] The model class for the query, default to
|
* @param {ModelClass} [targetClass] The model class for the query, default to
|
||||||
* the declaring model
|
* the declaring model
|
||||||
*/
|
*/
|
||||||
DataAccessObject.scope = function (name, query, targetClass) {
|
DataAccessObject.scope = function (name, query, targetClass, methods, options) {
|
||||||
defineScope(this, targetClass || this, name, query);
|
var cls = this;
|
||||||
|
if (options && options.isStatic === false) {
|
||||||
|
cls = cls.prototype;
|
||||||
|
}
|
||||||
|
defineScope(cls, targetClass || cls, name, query, methods, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -378,7 +378,7 @@ function isModelDataSourceAttached(model) {
|
||||||
DataSource.prototype.defineScopes = function (modelClass, scopes) {
|
DataSource.prototype.defineScopes = function (modelClass, scopes) {
|
||||||
if(scopes) {
|
if(scopes) {
|
||||||
for(var s in scopes) {
|
for(var s in scopes) {
|
||||||
defineScope(modelClass, modelClass, s, scopes[s]);
|
defineScope(modelClass, modelClass, s, scopes[s], {}, scopes[s].options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -564,7 +564,7 @@ RelationDefinition.hasMany = function hasMany(modelFrom, modelTo, params) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return filter;
|
return filter;
|
||||||
}, scopeMethods);
|
}, scopeMethods, definition.options);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1579,7 +1579,7 @@ RelationDefinition.embedsMany = function embedsMany(modelFrom, modelTo, params)
|
||||||
// Mix the property and scoped methods into the prototype class
|
// Mix the property and scoped methods into the prototype class
|
||||||
var scopeDefinition = defineScope(modelFrom.prototype, modelTo, accessorName, function () {
|
var scopeDefinition = defineScope(modelFrom.prototype, modelTo, accessorName, function () {
|
||||||
return {};
|
return {};
|
||||||
}, scopeMethods);
|
}, scopeMethods, definition.options);
|
||||||
|
|
||||||
scopeDefinition.related = scopeMethods.related;
|
scopeDefinition.related = scopeMethods.related;
|
||||||
};
|
};
|
||||||
|
@ -1985,7 +1985,7 @@ RelationDefinition.referencesMany = function referencesMany(modelFrom, modelTo,
|
||||||
// Mix the property and scoped methods into the prototype class
|
// Mix the property and scoped methods into the prototype class
|
||||||
var scopeDefinition = defineScope(modelFrom.prototype, modelTo, relationName, function () {
|
var scopeDefinition = defineScope(modelFrom.prototype, modelTo, relationName, function () {
|
||||||
return {};
|
return {};
|
||||||
}, scopeMethods);
|
}, scopeMethods, definition.options);
|
||||||
|
|
||||||
scopeDefinition.related = scopeMethods.related; // bound to definition
|
scopeDefinition.related = scopeMethods.related; // bound to definition
|
||||||
};
|
};
|
||||||
|
|
31
lib/scope.js
31
lib/scope.js
|
@ -8,11 +8,13 @@ exports.defineScope = defineScope;
|
||||||
exports.mergeQuery = mergeQuery;
|
exports.mergeQuery = mergeQuery;
|
||||||
|
|
||||||
function ScopeDefinition(definition) {
|
function ScopeDefinition(definition) {
|
||||||
this.sourceModel = definition.sourceModel;
|
this.isStatic = definition.isStatic;
|
||||||
this.targetModel = definition.targetModel || definition.sourceModel;
|
this.modelFrom = definition.modelFrom;
|
||||||
|
this.modelTo = definition.modelTo || definition.modelFrom;
|
||||||
this.name = definition.name;
|
this.name = definition.name;
|
||||||
this.params = definition.params;
|
this.params = definition.params;
|
||||||
this.methods = definition.methods;
|
this.methods = definition.methods;
|
||||||
|
this.options = definition.options;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopeDefinition.prototype.related = function(receiver, scopeParams, condOrRefresh, cb) {
|
ScopeDefinition.prototype.related = function(receiver, scopeParams, condOrRefresh, cb) {
|
||||||
|
@ -40,7 +42,7 @@ ScopeDefinition.prototype.related = function(receiver, scopeParams, condOrRefres
|
||||||
|| actualRefresh) {
|
|| actualRefresh) {
|
||||||
// It either doesn't hit the cache or refresh is required
|
// It either doesn't hit the cache or refresh is required
|
||||||
var params = mergeQuery(actualCond, scopeParams);
|
var params = mergeQuery(actualCond, scopeParams);
|
||||||
return this.targetModel.find(params, function (err, data) {
|
return this.modelTo.find(params, function (err, data) {
|
||||||
if (!err && saveOnCache) {
|
if (!err && saveOnCache) {
|
||||||
defineCachedRelations(self);
|
defineCachedRelations(self);
|
||||||
self.__cachedRelations[name] = data;
|
self.__cachedRelations[name] = data;
|
||||||
|
@ -62,7 +64,7 @@ ScopeDefinition.prototype.related = function(receiver, scopeParams, condOrRefres
|
||||||
* to return the query object
|
* to return the query object
|
||||||
* @param methods An object of methods keyed by the method name to be bound to the class
|
* @param methods An object of methods keyed by the method name to be bound to the class
|
||||||
*/
|
*/
|
||||||
function defineScope(cls, targetClass, name, params, methods) {
|
function defineScope(cls, targetClass, name, params, methods, options) {
|
||||||
|
|
||||||
// collect meta info about scope
|
// collect meta info about scope
|
||||||
if (!cls._scopeMeta) {
|
if (!cls._scopeMeta) {
|
||||||
|
@ -79,14 +81,27 @@ function defineScope(cls, targetClass, name, params, methods) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
// Check if the cls is the class itself or its prototype
|
||||||
|
var isStatic = (typeof cls === 'function') || options.isStatic || false;
|
||||||
var definition = new ScopeDefinition({
|
var definition = new ScopeDefinition({
|
||||||
sourceModel: cls,
|
isStatic: isStatic,
|
||||||
targetModel: targetClass,
|
modelFrom: cls,
|
||||||
|
modelTo: targetClass,
|
||||||
name: name,
|
name: name,
|
||||||
params: params,
|
params: params,
|
||||||
methods: methods
|
methods: methods,
|
||||||
|
options: options || {}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if(isStatic) {
|
||||||
|
cls.scopes = cls.scopes || {};
|
||||||
|
cls.scopes[name] = definition;
|
||||||
|
} else {
|
||||||
|
cls.constructor.scopes = cls.constructor.scopes || {};
|
||||||
|
cls.constructor.scopes[name] = definition;
|
||||||
|
}
|
||||||
|
|
||||||
// Define a property for the scope
|
// Define a property for the scope
|
||||||
Object.defineProperty(cls, name, {
|
Object.defineProperty(cls, name, {
|
||||||
enumerable: false,
|
enumerable: false,
|
||||||
|
@ -115,7 +130,7 @@ function defineScope(cls, targetClass, name, params, methods) {
|
||||||
f._scope = typeof definition.params === 'function' ?
|
f._scope = typeof definition.params === 'function' ?
|
||||||
definition.params.call(self) : definition.params;
|
definition.params.call(self) : definition.params;
|
||||||
|
|
||||||
f._targetClass = definition.targetModel.modelName;
|
f._targetClass = definition.modelTo.modelName;
|
||||||
if (f._scope.collect) {
|
if (f._scope.collect) {
|
||||||
f._targetClass = i8n.capitalize(f._scope.collect);
|
f._targetClass = i8n.capitalize(f._scope.collect);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "loopback-datasource-juggler",
|
"name": "loopback-datasource-juggler",
|
||||||
"version": "2.2.2",
|
"version": "2.3.1",
|
||||||
"description": "LoopBack DataSoure Juggler",
|
"description": "LoopBack DataSoure Juggler",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"StrongLoop",
|
"StrongLoop",
|
||||||
|
|
|
@ -284,17 +284,17 @@ describe('relations', function () {
|
||||||
Address.create({name: 'z'}, function (err, address) {
|
Address.create({name: 'z'}, function (err, address) {
|
||||||
patient.address(address);
|
patient.address(address);
|
||||||
patient.save(function() {
|
patient.save(function() {
|
||||||
verify(physician);
|
verify(physician, address.id);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
function verify(physician) {
|
function verify(physician, addressId) {
|
||||||
physician.patients({include: 'address'}, function (err, ch) {
|
physician.patients({include: 'address'}, function (err, ch) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(ch);
|
should.exist(ch);
|
||||||
ch.should.have.lengthOf(1);
|
ch.should.have.lengthOf(1);
|
||||||
ch[0].addressId.should.equal(1);
|
ch[0].addressId.should.eql(addressId);
|
||||||
var address = ch[0].address();
|
var address = ch[0].address();
|
||||||
should.exist(address);
|
should.exist(address);
|
||||||
address.should.be.an.instanceof(Address);
|
address.should.be.an.instanceof(Address);
|
||||||
|
|
|
@ -9,6 +9,14 @@ describe('scope', function () {
|
||||||
db = getSchema();
|
db = getSchema();
|
||||||
Railway = db.define('Railway', {
|
Railway = db.define('Railway', {
|
||||||
URID: {type: String, index: true}
|
URID: {type: String, index: true}
|
||||||
|
}, {
|
||||||
|
scopes: {
|
||||||
|
highSpeed: {
|
||||||
|
where: {
|
||||||
|
highSpeed: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
Station = db.define('Station', {
|
Station = db.define('Station', {
|
||||||
USID: {type: String, index: true},
|
USID: {type: String, index: true},
|
||||||
|
@ -25,8 +33,14 @@ describe('scope', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should define scope using options.scopes', function () {
|
||||||
|
Railway.scopes.should.have.property('highSpeed');
|
||||||
|
Railway.highSpeed.should.be.function;
|
||||||
|
});
|
||||||
|
|
||||||
it('should define scope with query', function (done) {
|
it('should define scope with query', function (done) {
|
||||||
Station.scope('active', {where: {isActive: true}});
|
Station.scope('active', {where: {isActive: true}});
|
||||||
|
Station.scopes.should.have.property('active');
|
||||||
Station.active.create(function (err, station) {
|
Station.active.create(function (err, station) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(station);
|
should.exist(station);
|
||||||
|
|
Loading…
Reference in New Issue