Skip to content

Commit d77b365

Browse files
committed
feat(builder): add support to pass an object as argument in where and whereIn methods
Closes #205
1 parent 8f08c8f commit d77b365

File tree

5 files changed

+161
-2
lines changed

5 files changed

+161
-2
lines changed

docs/content/en/api/query-builder-methods.md

+16
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@ await Model.where('status', 'active')
8080
await Model.where(['user', 'status'], 'active')
8181
```
8282

83+
#### Object
84+
85+
<alert type="success">Available in version >= v1.10.0</alert>
86+
87+
```js
88+
await Model.where({ user: { status: 'active' } })
89+
```
90+
8391
## `whereIn`
8492
- Arguments: `(field, array)`
8593
- Returns: `self`
@@ -98,6 +106,14 @@ await Model.whereIn('id', [1, 2, 3])
98106
await Model.whereIn(['user', 'id'], [1, 2, 3])
99107
```
100108

109+
#### Object
110+
111+
<alert type="success">Available in version >= v1.10.0</alert>
112+
113+
```js
114+
await Model.where({ user: { id: [1, 2, 3] } })
115+
```
116+
101117
## `orderBy`
102118
- Arguments: `(...args)`
103119
- Returns: `self`

docs/content/en/building-the-query.md

+56
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,34 @@ So we can filter our **Posts** to only get results where `status` of `user` is `
276276
</code-block>
277277
</code-group>
278278

279+
#### Using an Object
280+
281+
<alert type="success">Available in version >= v1.10.0</alert>
282+
283+
Now is also possible to pass an object.
284+
285+
<code-group>
286+
<code-block label="Query" active>
287+
288+
```js
289+
const posts = await Post.where({
290+
status: 'published',
291+
user: {
292+
status: 'active'
293+
}
294+
}).get()
295+
```
296+
297+
</code-block>
298+
<code-block label="Request">
299+
300+
```http request
301+
GET /posts?filter[status]=published&filter[user][status]=active
302+
```
303+
304+
</code-block>
305+
</code-group>
306+
279307
### Evaluating Multiple Values
280308

281309
See the [API reference](/api/query-builder-methods#wherein)
@@ -332,6 +360,34 @@ So we can filter our **Posts** to only get results where `status` of `user` is `
332360
</code-block>
333361
</code-group>
334362

363+
#### Using an Object
364+
365+
<alert type="success">Available in version >= v1.10.0</alert>
366+
367+
Now is also possible to pass an object.
368+
369+
<code-group>
370+
<code-block label="Query" active>
371+
372+
```js
373+
const posts = await Post.where({
374+
status: ['published', 'archived'],
375+
user: {
376+
status: ['active', 'inactive']
377+
}
378+
}).get()
379+
```
380+
381+
</code-block>
382+
<code-block label="Request">
383+
384+
```http request
385+
GET /posts?filter[status]=published,archived&filter[user][status]=active,inactive
386+
```
387+
388+
</code-block>
389+
</code-group>
390+
335391
## Sorting
336392

337393
See the [API reference](/api/query-builder-methods#orderby)

index.d.ts

+54
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,17 @@ declare class StaticModel {
150150
value: string | number | boolean
151151
): InstanceType<M>
152152

153+
/**
154+
* Add a basic where clause to the query.
155+
*
156+
* @see {@link https://robsontenorio.github.io/vue-api-query/api/query-builder-methods#where|API Reference}
157+
* @see {@link https://robsontenorio.github.io/vue-api-query/building-the-query#evaluating-a-single-value|Building the Query}
158+
*/
159+
static where<M extends typeof Model> (
160+
this: M,
161+
filter: Record<string, any>
162+
): InstanceType<M>
163+
153164
/**
154165
* Add a "where in" clause to the query.
155166
*
@@ -162,6 +173,17 @@ declare class StaticModel {
162173
values: (string | number | boolean)[]
163174
): InstanceType<M>
164175

176+
/**
177+
* Add a "where in" clause to the query.
178+
*
179+
* @see {@link https://robsontenorio.github.io/vue-api-query/api/query-builder-methods#wherein|API Reference}
180+
* @see {@link https://robsontenorio.github.io/vue-api-query/building-the-query#evaluating-multiple-values|Building the Query}
181+
*/
182+
static whereIn<M extends typeof Model> (
183+
this: M,
184+
filter: Record<string, any>
185+
): InstanceType<M>
186+
165187
/**
166188
* Add an "order by" clause to the query.
167189
*
@@ -519,6 +541,14 @@ export class Model extends StaticModel {
519541
*/
520542
where (field: string | string[], value: string | number | boolean): this
521543

544+
/**
545+
* Add a basic where clause to the query.
546+
*
547+
* @see {@link https://robsontenorio.github.io/vue-api-query/api/query-builder-methods#where|API Reference}
548+
* @see {@link https://robsontenorio.github.io/vue-api-query/building-the-query#evaluating-a-single-value|Building the Query}
549+
*/
550+
where (filter: Record<string, any>): this
551+
522552
/**
523553
* Add a "where in" clause to the query.
524554
*
@@ -527,6 +557,14 @@ export class Model extends StaticModel {
527557
*/
528558
whereIn (field: string | string[], array: (string | number | boolean)[]): this
529559

560+
/**
561+
* Add a "where in" clause to the query.
562+
*
563+
* @see {@link https://robsontenorio.github.io/vue-api-query/api/query-builder-methods#wherein|API Reference}
564+
* @see {@link https://robsontenorio.github.io/vue-api-query/building-the-query#evaluating-multiple-values|Building the Query}
565+
*/
566+
whereIn (filter: Record<string, any>): this
567+
530568
/**
531569
* Add an "order by" clause to the query.
532570
*
@@ -813,6 +851,14 @@ declare class Builder {
813851
*/
814852
where (field: string | string[], value: string | number | boolean): this
815853

854+
/**
855+
* Add a basic where clause to the query.
856+
*
857+
* @see {@link https://robsontenorio.github.io/vue-api-query/api/query-builder-methods#where|API Reference}
858+
* @see {@link https://robsontenorio.github.io/vue-api-query/building-the-query#evaluating-a-single-value|Building the Query}
859+
*/
860+
where (filter: Record<string, any>): this
861+
816862
/**
817863
* Add a "where in" clause to the query.
818864
*
@@ -821,6 +867,14 @@ declare class Builder {
821867
*/
822868
whereIn (field: string | string[], array: (string | number | boolean)[]): this
823869

870+
/**
871+
* Add a "where in" clause to the query.
872+
*
873+
* @see {@link https://robsontenorio.github.io/vue-api-query/api/query-builder-methods#wherein|API Reference}
874+
* @see {@link https://robsontenorio.github.io/vue-api-query/building-the-query#evaluating-multiple-values|Building the Query}
875+
*/
876+
whereIn (filter: Record<string, any>): this
877+
824878
/**
825879
* Add an "order by" clause to the query.
826880
*

src/Builder.js

+12-2
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export default class Builder {
100100
}
101101

102102
where(key, value) {
103-
if (key === undefined || value === undefined) {
103+
if (key === undefined || (typeof key !== 'object' && value === undefined)) {
104104
throw new Error('The KEY and VALUE are required on where() method.')
105105
}
106106

@@ -112,6 +112,11 @@ export default class Builder {
112112
const [_key, _value] = this._nestedFilter(key, value)
113113

114114
this.filters[_key] = { ...this.filters[_key], ..._value }
115+
} else if (typeof key === 'object') {
116+
this.filters = {
117+
...this.filters,
118+
...key
119+
}
115120
} else {
116121
this.filters[key] = value
117122
}
@@ -120,7 +125,7 @@ export default class Builder {
120125
}
121126

122127
whereIn(key, array) {
123-
if (!Array.isArray(array)) {
128+
if (typeof key !== 'object' && !Array.isArray(array)) {
124129
throw new Error(
125130
'The second argument on whereIn() method must be an array.'
126131
)
@@ -130,6 +135,11 @@ export default class Builder {
130135
const [_key, _value] = this._nestedFilter(key, array)
131136

132137
this.filters[_key] = { ...this.filters[_key], ..._value }
138+
} else if (typeof key === 'object') {
139+
this.filters = {
140+
...this.filters,
141+
...key
142+
}
133143
} else {
134144
this.filters[key] = array
135145
}

tests/builder.test.js

+23
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,18 @@ describe('Query builder', () => {
133133
expect(post._builder.query()).toEqual(
134134
'?filter[schedule][start]=2020-11-27&filter[schedule][end]=2020-11-28'
135135
)
136+
137+
post = Post.where({ id: 1, title: 'Cool' }).when(true, (query) =>
138+
query.where({ user: { status: 'active' } })
139+
)
140+
141+
expect(post._builder.filters).toEqual({
142+
id: 1,
143+
title: 'Cool',
144+
user: {
145+
status: 'active'
146+
}
147+
})
136148
})
137149

138150
test('where() throws a exception when doest not have params or only first param', () => {
@@ -189,6 +201,17 @@ describe('Query builder', () => {
189201
expect(post._builder.query()).toEqual(
190202
'?filter[schedule][start]=2020-11-27,2020-11-28&filter[schedule][end]=2020-11-28,2020-11-29'
191203
)
204+
205+
post = Post.where({ status: ['ACTIVE', 'ARCHIVED'] }).when(true, (query) =>
206+
query.where({ user: { status: ['active', 'inactive'] } })
207+
)
208+
209+
expect(post._builder.filters).toEqual({
210+
status: ['ACTIVE', 'ARCHIVED'],
211+
user: {
212+
status: ['active', 'inactive']
213+
}
214+
})
192215
})
193216

194217
test('whereIn() throws a exception when second parameter is not a array', () => {

0 commit comments

Comments
 (0)