diff --git a/lib/persisted-model.js b/lib/persisted-model.js
index 9f4fe37b..be1b2549 100644
--- a/lib/persisted-model.js
+++ b/lib/persisted-model.js
@@ -142,15 +142,20 @@ module.exports = function(registry) {
};
/**
- * Find object by ID.
+ * Find object by ID with an optional filter for include/fields.
*
* @param {*} id Primary key value
+ * @options {Object} [filter] Optional Filter JSON object; see below.
+ * @property {String|Object|Array} fields Identify fields to include in return result.
+ *
See [Fields filter](http://docs.strongloop.com/display/LB/Fields+filter).
+ * @property {String|Object|Array} include See PersistedModel.include documentation.
+ *
See [Include filter](http://docs.strongloop.com/display/LB/Include+filter).
* @callback {Function} callback Callback function called with `(err, instance)` arguments. Required.
* @param {Error} err Error object; see [Error object](http://docs.strongloop.com/display/LB/Error+object).
* @param {Object} instance Model instance matching the specified ID or null if no instance matches.
*/
- PersistedModel.findById = function find(id, cb) {
+ PersistedModel.findById = function find(id, filter, cb) {
throwNotAttached(this.modelName, 'findById');
};
@@ -180,7 +185,7 @@ module.exports = function(registry) {
* @param {Array} models Model instances matching the filter, or null if none found.
*/
- PersistedModel.find = function find(params, cb) {
+ PersistedModel.find = function find(filter, cb) {
throwNotAttached(this.modelName, 'find');
};
@@ -209,7 +214,7 @@ module.exports = function(registry) {
* @param {Array} model First model instance that matches the filter or null if none found.
*/
- PersistedModel.findOne = function findOne(params, cb) {
+ PersistedModel.findOne = function findOne(filter, cb) {
throwNotAttached(this.modelName, 'findOne');
};
@@ -573,10 +578,12 @@ module.exports = function(registry) {
setRemoting(PersistedModel, 'findById', {
description: 'Find a model instance by id from the data source.',
accessType: 'READ',
- accepts: {
- arg: 'id', type: 'any', description: 'Model id', required: true,
- http: {source: 'path'}
- },
+ accepts: [
+ { arg: 'id', type: 'any', description: 'Model id', required: true,
+ http: {source: 'path'}},
+ { arg: 'filter', type: 'object',
+ description: 'Filter defining fields and include'}
+ ],
returns: {arg: 'data', type: typeName, root: true},
http: {verb: 'get', path: '/:id'},
rest: {after: convertNullToNotFoundError}
@@ -585,7 +592,7 @@ module.exports = function(registry) {
setRemoting(PersistedModel, 'find', {
description: 'Find all instances of the model matched by filter from the data source.',
accessType: 'READ',
- accepts: {arg: 'filter', type: 'object', description: 'Filter defining fields, where, order, offset, and limit'},
+ accepts: {arg: 'filter', type: 'object', description: 'Filter defining fields, where, include, order, offset, and limit'},
returns: {arg: 'data', type: [typeName], root: true},
http: {verb: 'get', path: '/'}
});
@@ -593,7 +600,7 @@ module.exports = function(registry) {
setRemoting(PersistedModel, 'findOne', {
description: 'Find first instance of the model matched by filter from the data source.',
accessType: 'READ',
- accepts: {arg: 'filter', type: 'object', description: 'Filter defining fields, where, order, offset, and limit'},
+ accepts: {arg: 'filter', type: 'object', description: 'Filter defining fields, where, include, order, offset, and limit'},
returns: {arg: 'data', type: typeName, root: true},
http: {verb: 'get', path: '/findOne'},
rest: {after: convertNullToNotFoundError}
diff --git a/test/model.test.js b/test/model.test.js
index 7b037adb..abe4f1d5 100644
--- a/test/model.test.js
+++ b/test/model.test.js
@@ -66,7 +66,7 @@ describe('Model / PersistedModel', function() {
describe.onServer('Remote Methods', function() {
- var User;
+ var User, Post;
var dataSource;
var app;
@@ -84,11 +84,22 @@ describe.onServer('Remote Methods', function() {
trackChanges: true
});
+ Post = PersistedModel.extend('post', {
+ id: { id: true, type: String, defaultFn: 'guid' },
+ title: String,
+ content: String
+ }, {
+ trackChanges: true
+ });
+
dataSource = loopback.createDataSource({
connector: loopback.Memory
});
User.attachTo(dataSource);
+ Post.attachTo(dataSource);
+
+ User.hasMany(Post);
User.login = function(username, password, fn) {
if (username === 'foo' && password === 'bar') {
@@ -163,6 +174,63 @@ describe.onServer('Remote Methods', function() {
done();
});
});
+
+ it('Call the findById with filter.fields using HTTP / REST', function(done) {
+ request(app)
+ .post('/users')
+ .send({first: 'x', last: 'y'})
+ .expect('Content-Type', /json/)
+ .expect(200)
+ .end(function(err, res) {
+ if (err) return done(err);
+ var userId = res.body.id;
+ assert(userId);
+ request(app)
+ .get('/users/' + userId + '?filter[fields]=first')
+ .expect('Content-Type', /json/)
+ .expect(200)
+ .end(function(err, res) {
+ if (err) return done(err);
+ assert.equal(res.body.first, 'x', 'first should be x');
+ assert(res.body.last === undefined, 'last should not be present');
+ done();
+ });
+ });
+ });
+
+ it('Call the findById with filter.include using HTTP / REST', function(done) {
+ request(app)
+ .post('/users')
+ .send({first: 'x', last: 'y'})
+ .expect('Content-Type', /json/)
+ .expect(200)
+ .end(function(err, res) {
+ if (err) return done(err);
+ var userId = res.body.id;
+ assert(userId);
+ request(app)
+ .post('/users/' + userId + '/posts')
+ .send({title: 'T1', content: 'C1'})
+ .expect('Content-Type', /json/)
+ .expect(200)
+ .end(function(err, res) {
+ if (err) return done(err);
+ var post = res.body;
+ request(app)
+ .get('/users/' + userId + '?filter[include]=posts')
+ .expect('Content-Type', /json/)
+ .expect(200)
+ .end(function(err, res) {
+ if (err) return done(err);
+ assert.equal(res.body.first, 'x', 'first should be x');
+ assert.equal(res.body.last, 'y', 'last should be y');
+ assert.deepEqual(post, res.body.posts[0]);
+ done();
+ });
+ });
+ });
+ });
+
});
describe('Model.beforeRemote(name, fn)', function() {
diff --git a/test/remoting.integration.js b/test/remoting.integration.js
index 76840f69..59a553af 100644
--- a/test/remoting.integration.js
+++ b/test/remoting.integration.js
@@ -114,7 +114,7 @@ describe('remoting - integration', function() {
'create(data:object):store POST /stores',
'upsert(data:object):store PUT /stores',
'exists(id:any):boolean GET /stores/:id/exists',
- 'findById(id:any):store GET /stores/:id',
+ 'findById(id:any,filter:object):store GET /stores/:id',
'find(filter:object):store GET /stores',
'findOne(filter:object):store GET /stores/findOne',
'updateAll(where:object,data:object) POST /stores/update',