diff --git a/lib/models/model.js b/lib/models/model.js index 24b9fc6c..99d899b4 100644 --- a/lib/models/model.js +++ b/lib/models/model.js @@ -185,10 +185,9 @@ Model.setup = function () { // resolve relation functions sharedClass.resolve(function resolver(define) { - var relations = ModelCtor.relations; - if (!relations) { - return; - } + + var relations = ModelCtor.relations || {}; + // get the relations for (var relationName in relations) { var relation = relations[relationName]; @@ -201,13 +200,16 @@ Model.setup = function () { relation.type === 'embedsMany' || relation.type === 'referencesMany') { ModelCtor.hasManyRemoting(relationName, relation, define); - ModelCtor.scopeRemoting(relationName, relation, define); - } else { - ModelCtor.scopeRemoting(relationName, relation, define); } } + + // handle scopes + var scopes = ModelCtor.scopes || {}; + for (var scopeName in scopes) { + ModelCtor.scopeRemoting(scopeName, scopes[scopeName], define); + } }); - + return ModelCtor; }; @@ -474,30 +476,32 @@ Model.hasManyRemoting = function (relationName, relation, define) { } }; -Model.scopeRemoting = function(relationName, relation, define) { - var pathName = (relation.options.http && relation.options.http.path) || relationName; - var toModelName = relation.modelTo.modelName; +Model.scopeRemoting = function(scopeName, scope, define) { + var pathName = (scope.options && scope.options.http && scope.options.http.path) + || scopeName; + var isStatic = scope.isStatic; + var toModelName = scope.modelTo.modelName; - define('__get__' + relationName, { - isStatic: false, + define('__get__' + scopeName, { + isStatic: isStatic, http: {verb: 'get', path: '/' + pathName}, accepts: {arg: 'filter', type: 'object'}, - description: 'Queries ' + relationName + ' of ' + this.modelName + '.', - returns: {arg: relationName, type: [toModelName], root: true} + description: 'Queries ' + scopeName + ' of ' + this.modelName + '.', + returns: {arg: scopeName, type: [toModelName], root: true} }); - define('__create__' + relationName, { - isStatic: false, + define('__create__' + scopeName, { + isStatic: isStatic, http: {verb: 'post', path: '/' + pathName}, accepts: {arg: 'data', type: toModelName, http: {source: 'body'}}, - description: 'Creates a new instance in ' + relationName + ' of this model.', + description: 'Creates a new instance in ' + scopeName + ' of this model.', returns: {arg: 'data', type: toModelName, root: true} }); - define('__delete__' + relationName, { - isStatic: false, + define('__delete__' + scopeName, { + isStatic: isStatic, http: {verb: 'delete', path: '/' + pathName}, - description: 'Deletes all ' + relationName + ' of this model.' + description: 'Deletes all ' + scopeName + ' of this model.' }); }; diff --git a/test/fixtures/simple-integration-app/models.json b/test/fixtures/simple-integration-app/models.json index 41acde0c..6f4e7535 100644 --- a/test/fixtures/simple-integration-app/models.json +++ b/test/fixtures/simple-integration-app/models.json @@ -45,6 +45,13 @@ "public": true, "dataSource": "db", "options": { + "scopes": { + "superStores": { + "where": { + "size": "super" + } + } + }, "relations": { "widgets": { "model": "widget", diff --git a/test/relations.integration.js b/test/relations.integration.js index 92e4e9bb..c0e2d28c 100644 --- a/test/relations.integration.js +++ b/test/relations.integration.js @@ -25,6 +25,16 @@ describe('relations - integration', function () { this.app.models.widget.destroyAll(done); }); + describe('/store/superStores', function() { + it('should invoke scoped methods remotely', function(done) { + this.get('/api/stores/superStores') + .expect(200, function(err, res) { + expect(res.body).to.be.array; + done(); + }); + }); + }); + describe('/store/:id/widgets', function () { beforeEach(function() { this.url = '/api/stores/' + this.store.id + '/widgets';