Skip to content

Commit 32b24c6

Browse files
committed
[Feature] Allow custom sort methods to be implemented on adapters
See example in sorting chapter in the docs. Closes #549
1 parent a757f4c commit 32b24c6

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. This projec
44

55
## Unreleased
66

7+
### Added
8+
- [#549](https://github.com/cloudcreativity/laravel-json-api/issues/549)
9+
Can now add sort methods to an Eloquent adapter if sorting is more complex than just sorting by
10+
a column value.
11+
712
### Fixed
813
- The error translator will now detect if the translated value is identical to the translation
914
key path, and return `null` when it is. This fixes behaviour that changed in Laravel 7.28.

docs/fetching/sorting.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,25 @@ class Adapter extends AbstractAdapter
142142

143143
}
144144
```
145+
146+
To implement more complex sorting where you need access to the Eloquent query builder instance,
147+
you can add methods to your adapter. The method name must follow the pattern `sortBy<Name>`,
148+
where `<Name>` is the camel cased name of the JSON API sort field.
149+
150+
For example, if you had a JSON API sort field called `likes`, you could implement the
151+
`sortByLikes` method on your adapter. This will receive the query builder instance and
152+
the direction of the sort (either `asc` or `desc`).
153+
154+
```php
155+
class Adapter extends AbstractAdapter
156+
{
157+
// ...
158+
159+
protected function sortByLikes($query, $direction): void
160+
{
161+
$query->withCount('likes')
162+
->orderBy('likes_count', $direction);
163+
}
164+
165+
}
166+
```

src/Eloquent/Concerns/SortsModels.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,21 @@ protected function defaultSort()
101101
/**
102102
* @param Builder $query
103103
* @param SortParameterInterface $param
104+
* @return void
104105
*/
105106
protected function sortBy($query, SortParameterInterface $param)
106107
{
108+
$direction = $param->isAscending() ? 'asc' : 'desc';
109+
$method = 'sortBy' . Str::classify($param->getField());
110+
111+
if (method_exists($this, $method)) {
112+
$this->{$method}($query, $direction);
113+
return;
114+
}
115+
107116
$column = $this->getQualifiedSortColumn($query, $param->getField());
108-
$order = $param->isAscending() ? 'asc' : 'desc';
109117

110-
$query->orderBy($column, $order);
118+
$query->orderBy($column, $direction);
111119
}
112120

113121
/**

0 commit comments

Comments
 (0)