Skip to content

Commit ed5abe0

Browse files
samatcdphpsa
andauthored
Allow filters on related models (#43)
* Allow filtering on related fields * Updated readme for filter fields * Apply fixes from StyleCI (#44) Co-authored-by: Craig Smith <[email protected]>
1 parent 49d590f commit ed5abe0

File tree

3 files changed

+48
-5
lines changed

3 files changed

+48
-5
lines changed

README.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ protected static $allowedScopes = [
127127

128128
Given the above `$allowedScopes` array, your API consumers will now be able to request `?fullname=John`. The query parameter value will be passed to your scope function in your Eloquent Model.
129129

130+
## Filtering on related models
131+
132+
You can easily filter using any related model that is configured for `include`. Simply specify `?filter[model.field]=123` in your query string. The same filter options above apply to related fields.
133+
130134

131135
# Fields, Relationships, Sorting & Pagination
132136

@@ -141,7 +145,16 @@ By default all fields are returned, you can limit that to specific fields in the
141145

142146
## Relationships
143147

144-
* Using the relationships defined in your models, you can pass a comma delimited list eg `include=join1,join2` which will return those joins (one or many)
148+
* Using the relationships defined in your models, you can pass a comma delimited list eg `include=join1,join2` which will return those joins (one or many).
149+
150+
Simply add a `protected static $mapResources` to your `Resource` to define which resources to assign your related data. E.e., for a one to many relationship, you should specify a collection, and a one-to-one relationship specify the related resource directly. This will allow the API to properly format the related record.
151+
152+
```
153+
protected static $mapResources = [
154+
'notes' => NotesCollection::class,
155+
'owner' => OwnerResource::class
156+
];
157+
```
145158

146159
## Sorting
147160

src/Contracts/Parser.php

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ protected function parseFilterParams(): void
127127

128128
foreach ($where as $whr) {
129129
if (strpos($whr['key'], '.') > 0) {
130-
//@TODO: test if exists in the withs, if not continue out to exclude from the qbuild
131-
//continue;
130+
$this->setWhereHasClause($whr);
131+
continue;
132132
} elseif (! in_array($whr['key'], $tableColumns)) {
133133
continue;
134134
}
@@ -151,12 +151,42 @@ protected function parseMethodParams($request): void
151151
}
152152
}
153153

154+
protected function setWhereHasClause(array $where): void
155+
{
156+
[$with, $key] = explode('.', $where['key']);
157+
158+
$sub = self::$model->{$with}()->getRelated();
159+
$fields = $this->getTableColumns($sub);
160+
161+
if (! in_array($key, $fields)) {
162+
return;
163+
}
164+
165+
$this->repository->whereHas($with, function ($q) use ($where, $key) {
166+
switch ($where['type']) {
167+
case 'In':
168+
if (! empty($where['values'])) {
169+
$q->whereIn($key, $where['values']);
170+
}
171+
break;
172+
case 'NotIn':
173+
if (! empty($where['values'])) {
174+
$q->whereNotIn($key, $where['values']);
175+
}
176+
break;
177+
case 'Basic':
178+
$q->where($key, $where['value'], $where['operator']);
179+
break;
180+
}
181+
});
182+
}
183+
154184
/**
155185
* set the Where clause.
156186
*
157187
* @param array $where the where clause
158188
*/
159-
protected function setWhereClause($where): void
189+
protected function setWhereClause(array $where): void
160190
{
161191
switch ($where['type']) {
162192
case 'In':

src/Repository/BaseRepository.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ public function with($relations)
403403
$relations = func_get_args();
404404
}
405405

406-
$this->with = $relations;
406+
$this->with = array_unique(array_merge($this->with, $relations));
407407

408408
return $this;
409409
}

0 commit comments

Comments
 (0)