From e102fd08823cdc8cca6f79da8a1edca9289efe27 Mon Sep 17 00:00:00 2001 From: Alec Hirsch Date: Fri, 10 Feb 2017 17:56:53 -0500 Subject: [PATCH 1/2] Added ability for user to modify the query builder before execution --- README.md | 6 ++++-- src/index.js | 8 +++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 40c24be..1c366f3 100644 --- a/README.md +++ b/README.md @@ -77,11 +77,11 @@ If you're returning a single resource from a call such as `GET /customers/1`, ma ## API -`fetchJsonApi(options, isCollection, type)` - calling `fetchJsonApi` with no options is just like a plain call to `Model#fetch` or `Model#fetchAll`. Note that in addition to the options below, you may also pass anything you can pass to `Model#fetch` or `Model#fetchAll`. +`fetchJsonApi(options, isCollection, type, additionalQuery)` - calling `fetchJsonApi` with no options is just like a plain call to `Model#fetch` or `Model#fetchAll`. Note that in addition to the options below, you may also pass anything you can pass to `Model#fetch` or `Model#fetchAll`. `options` | Description :------------- | :------------- -filter _object_ | Filters a result set based specific field. Example: `/pets?filter[name]=max` would only return pets named max. Keywords can be added to filters to give more control over the results. Example: `/pets?filterType[pet][like]=ax` would only return pets that have "ax" in their name. The supported types are "like", "not", "lt", "lte", "gt", and "gte". Both "like" and "not" support multiple values by comma separation. NOTE: This is not supported by JSON API spec. +filter _object_ | Filters a result set based specific field. Example: `/pets?filter[name]=max` would only return pets named max. Keywords can be added to filters to give more control over the results. Example: `/pets?filterType[like][pet]=ax` would only return pets that have "ax" in their name. The supported types are "like", "not", "lt", "lte", "gt", and "gte". Both "like" and "not" support multiple values by comma separation. NOTE: This is not supported by JSON API spec. fields _object_ | Limits the fields returned as part of the record. Example: `/pets?fields[pets]=name` would return pet records with only the name field rather than every field. include _array_ | Returns relationships as part of the payload. Example: `/pets?include=owner` would return the pet record in addition to the full record of its owner. _Note:_ you may override an `include` parameter with your own Knex function rather than just a string representing the relationship name. page _object/false_ | Paginates the result set. Example: `/pets?page[limit]=25&page[offset]=0` would return the first 25 records. If you've passed default pagination parameters to the plugin, but would like to disable paging on a specific call, just set `page` to `false`. @@ -93,6 +93,8 @@ See the **[specific section of the JSON API spec](http://jsonapi.org/format/#fet `type` - by default, the JSON API resource type will be set using the `tableName` defined in your Bookshelf model. If your resource type is different, you can pass the resource type into `fetchJsonApi` directly. +`additionalQuery` - allows you to modify the query builder prior to to execution of the query. This must be a function that takes in the knex Query Builder object. + ### Pagination and Sorting Under the hood, this plugin uses the excellent [bookshelf-page](https://github.com/anyong/bookshelf-page) plugin. Please see the available options that can be passed in via the `page` parameter. diff --git a/src/index.js b/src/index.js index 9e2af66..7d72982 100644 --- a/src/index.js +++ b/src/index.js @@ -10,6 +10,7 @@ import { isArray as _isArray, isObject as _isObject, isObjectLike as _isObjectLike, + isFunction as _isFunction, forIn as _forIn, keys as _keys, map as _map, @@ -57,7 +58,7 @@ export default (Bookshelf, options = {}) => { * with the model. * @return {Promise} */ - const fetchJsonApi = function (opts, isCollection = true, type) { + const fetchJsonApi = function (opts, isCollection = true, type, additionalQuery) { opts = opts || {}; @@ -628,6 +629,11 @@ export default (Bookshelf, options = {}) => { // Apply sparse fieldsets internals.buildFields(fields); + // Apply extra query which was passed in as a parameter + if (_isFunction(additionalQuery)){ + internals.model.query(additionalQuery); + } + // Assign default paging options if they were passed to the plugin // and no pagination parameters were passed directly to the method. if (isCollection && From 78fdb4c8e4c39e024bcb50912fc971b625fd1eb2 Mon Sep 17 00:00:00 2001 From: Alec Hirsch Date: Fri, 10 Feb 2017 23:02:34 -0500 Subject: [PATCH 2/2] added test case for additional query --- test/index.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/index.js b/test/index.js index 178989d..20c73a8 100644 --- a/test/index.js +++ b/test/index.js @@ -589,4 +589,29 @@ describe('bookshelf-jsonapi-params', () => { }); }); }); + + describe('pass a query builder function as fourth parameter', () => { + + it('should sum up the ages of people that have an age of 25 or less', (done) => { + + PersonModel + .forge() + .fetchJsonApi({ + filter: { + lte: { + age: 25 + } + } + }, false, undefined, (qb) => { + + qb.sum('age as ageSum'); + }) + .then((result) => { + + expect(result).to.be.an('object'); + expect(result.get('ageSum')).to.equal(37); + done(); + }); + }); + }); });