Skip to content

Commit 95f8082

Browse files
committed
- Added modify query docs
1 parent 05b1aa0 commit 95f8082

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"position": 1.5,
3+
"label": "Advanced Usage",
4+
"collapsible": true,
5+
"collapsed": false,
6+
"link": {
7+
"type": "generated-index",
8+
"slug": "/query-builder/_categories/advanced-usage",
9+
"description": "How to achieve more complex requirements"
10+
}
11+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
---
2+
title: Supporting complex selects
3+
sidebar_position: 1
4+
---
5+
6+
Sometimes you might need to conditionally include some columns through some query scopes that might not be in the original database table.
7+
A common scenario is including distance for coordinate fields when a user supplies a latitude and longitude.
8+
9+
For these scenarios, you can override the `modifyQuery` method to call these scopes.
10+
11+
```php
12+
// IslandsController.php
13+
14+
protected function modifyQuery(\Spatie\QueryBuilder\QueryBuilder $query): \Spatie\QueryBuilder\QueryBuilder
15+
{
16+
if (request()->has('lat') && request()->has('lng')) {
17+
if ($this->sorts()->has('distance') || $this->fields()->has('distance')) {
18+
$query->withDistance('islands.coordinates', new Point(request()->input('lat'), request()->input('lng'), Srid::WGS84));
19+
}
20+
}
21+
22+
return $query;
23+
}
24+
```
25+
26+
Notice the calls to the `$this->sorts()` and `$this->fields()` methods. These are helper methods to retrieve the `sorts` and `fields` of the current `QueryBuilder` request.
27+
The following helper methods are included in the Api controllers.
28+
29+
- `sorts()`
30+
- `fields()`
31+
- `includes()`
32+
- `filters()`
33+
- `appends()`
34+
35+
You can use the `modifyQuery` method to conditionally eager load relations as well to prevent N + 1 queries.
36+
37+
```php
38+
protected function modifyQuery(\Spatie\QueryBuilder\QueryBuilder $query): \Spatie\QueryBuilder\QueryBuilder
39+
{
40+
$fields = $this->fields()->isNotEmpty() ? $this->fields()->get('_') : [];
41+
42+
if ((is_array($fields) && in_array('formatted_name', $fields)) || $this->appends()->has('formatted_name')) {
43+
$query->with('atoll');
44+
}
45+
46+
return $query;
47+
}
48+
```
49+
50+
The `$this->fields()->get('_')` will return the fields requested for the main model.
51+
52+
For complex selects, you might need to dynamically set the allowed fields and sorts as well.
53+
54+
```php
55+
public function getAllowedFields(): array
56+
{
57+
$fields = \Schema::getColumnListing('islands');
58+
59+
if (request()->has('lat') && request()->has('lng')) {
60+
$fields[] = 'distance';
61+
}
62+
63+
return array_diff($fields, (new Island)->getHidden());
64+
}
65+
66+
public function getAllowedSorts(): array
67+
{
68+
$sorts = [
69+
'id',
70+
'created_at',
71+
'updated_at',
72+
'name',
73+
'code',
74+
'land_survey_code',
75+
'order_column',
76+
];
77+
78+
if (request()->has('lat') && request()->has('lng')) {
79+
$sorts[] = 'distance';
80+
}
81+
82+
return $sorts;
83+
}
84+
```

0 commit comments

Comments
 (0)