Skip to content

Commit 751d882

Browse files
committed
Allow scoping individual queries within Eloquent union builder
1 parent d9a6143 commit 751d882

File tree

2 files changed

+37
-26
lines changed

2 files changed

+37
-26
lines changed

src/Laravel/EloquentCollection.php

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,25 +50,27 @@ public function endpoints(): array
5050

5151
public function query(Context $context): object
5252
{
53-
$queries = array_map(function ($resource) use ($context) {
53+
$queries = [];
54+
55+
foreach ($this->eloquentResources($context) as $resource) {
5456
$keyName = $resource->newModel($context)->getQualifiedKeyName();
5557
$type = $resource->type();
5658

57-
$query = $resource
59+
$queries[$type] = $resource
5860
->query($context)
5961
->toBase()
6062
->select("$keyName as id")
6163
->selectRaw('? as type', [$type]);
64+
}
6265

63-
$this->scope($query, $type);
66+
$query = new UnionBuilder($queries);
6467

65-
return $query;
66-
}, $this->eloquentResources($context));
68+
$this->scope($query, $context);
6769

68-
return new UnionBuilder($queries);
70+
return $query;
6971
}
7072

71-
public function scope(Builder $query, string $type): void
73+
public function scope(UnionBuilder $query, Context $context): void
7274
{
7375
}
7476

src/Laravel/UnionBuilder.php

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
namespace Tobyz\JsonApiServer\Laravel;
44

55
use Illuminate\Contracts\Database\Query\Builder;
6+
use Illuminate\Support\Collection;
67

78
class UnionBuilder implements Builder
89
{
9-
private array $queryCalls = [];
1010
private array $outerQueryCalls = [];
1111
private ?int $limit = null;
1212
private int $offset = 0;
@@ -15,6 +15,27 @@ public function __construct(protected array $queries)
1515
{
1616
}
1717

18+
public function for(string $type): Builder
19+
{
20+
return $this->queries[$type];
21+
}
22+
23+
public function inner(callable $callback): static
24+
{
25+
foreach ($this->queries as $query) {
26+
$callback($query);
27+
}
28+
29+
return $this;
30+
}
31+
32+
public function outer(callable $callback): static
33+
{
34+
$this->outerQueryCalls[] = $callback;
35+
36+
return $this;
37+
}
38+
1839
public function skip(int $value): static
1940
{
2041
return $this->offset($value);
@@ -41,36 +62,21 @@ public function limit(?int $value): static
4162
return $this;
4263
}
4364

44-
public function orderBy($column, $direction = 'asc'): static
45-
{
46-
$this->queryCalls[] = fn($query) => $query
47-
->addSelect($column)
48-
->orderBy($column, $direction);
49-
50-
$this->outerQueryCalls[] = fn($query) => $query->orderBy($column, $direction);
51-
52-
return $this;
53-
}
54-
5565
public function count($columns = '*'): int
5666
{
5767
return $this->buildQuery()->count($columns);
5868
}
5969

60-
public function get($columns = ['*'])
70+
public function get($columns = ['*']): Collection
6171
{
6272
return $this->buildQuery()->get($columns);
6373
}
6474

65-
protected function buildQuery()
75+
protected function buildQuery(): Builder
6676
{
6777
$queries = array_map(fn($query) => clone $query, $this->queries);
6878

6979
foreach ($queries as $query) {
70-
foreach ($this->queryCalls as $call) {
71-
$call($query);
72-
}
73-
7480
if ($this->limit) {
7581
$query->take($this->offset + $this->limit);
7682
}
@@ -95,7 +101,10 @@ protected function buildQuery()
95101

96102
public function __call($method, $parameters)
97103
{
98-
$this->queryCalls[] = fn($query) => $query->$method(...$parameters);
104+
$callback = fn($query) => $query->$method(...$parameters);
105+
106+
$this->inner($callback);
107+
$this->outer($callback);
99108

100109
return $this;
101110
}

0 commit comments

Comments
 (0)