Skip to content

Commit

Permalink
add option to run multiple filters in single relation
Browse files Browse the repository at this point in the history
  • Loading branch information
emargareten committed Mar 10, 2024
1 parent 9f1dbff commit 4614603
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 1 deletion.
8 changes: 8 additions & 0 deletions src/Filterable.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public function applyFilter(Builder $query, mixed $filter, ?string $relation = n
}

if (str_contains($property, '.')) {
// Filter by relation
$query->whereRelation(
Str::before($property, '.'),
fn (Builder $query) => $model->applyFilter(
Expand All @@ -74,6 +75,13 @@ public function applyFilter(Builder $query, mixed $filter, ?string $relation = n
return;
}

if (is_array($operator)) {
// Filter by relation - multiple filters in single relation model
$query->whereHas($property, fn (Builder $query) => $query->filter($operator)); // @phpstan-ignore-line

return;
}

$filterTypes = $model->filterTypes ?? [];

if (! in_array($property, array_keys($filterTypes))) {
Expand Down
1 change: 1 addition & 0 deletions tests/Models/Comment.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class Comment extends Model
*/
public array $filterTypes = [
'body' => 'string',
'created_at' => 'date',
];

public function post(): BelongsTo
Expand Down
46 changes: 45 additions & 1 deletion tests/Unit/GeneralTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
])->count())->toBe(1);
});

test('can apply filters on relations', function () {
test('can apply filters on relations using dot notation', function () {
$post = Post::create(['content' => 'Lorem ipsum dolor sit amet.']);
$post->comments()->create(['body' => 'Lorem ipsum dolor sit amet.']);

Expand All @@ -94,6 +94,50 @@
->toBe(1);
});

test('can apply filters on relations using array', function () {
$post = Post::create(['content' => 'Lorem ipsum dolor sit amet.']);
$post->comments()->create([
'body' => 'Lorem ipsum dolor sit amet.',
'created_at' => '2020-01-01 00:00:00',
]);

$post2 = Post::create(['content' => 'Lorem ipsum dolor sit amet.']);
$post2->comments()->create([
'body' => 'Lorem ipsum dolor sit amet.',
'created_at' => '2021-01-01 00:00:00',
]);

$post3 = Post::create(['content' => 'Ipsum dolor sit amet.']);
$post3->comments()->create([
'body' => 'Ipsum dolor sit amet.',
]);

expect(Post::filter([
'property' => 'comments',
'operator' => [
'property' => 'body',
'operator' => 'contains',
'value' => 'Lorem',
],
])->count())->toBe(2)
->and(Post::filter([
'property' => 'comments',
'operator' => [
[
'property' => 'body',
'operator' => 'contains',
'value' => 'Lorem',
],
[
'property' => 'created_at',
'operator' => 'date:greater-than-or-equal',
'value' => '2021-01-01',
],
],
])->count())
->toBe(1);
});

test('dynamic filter on modal', function () {
Post::create(['views' => 10]);
Post::create(['views' => 20]);
Expand Down

0 comments on commit 4614603

Please sign in to comment.