From 03f64a16897ccc54d7c915cfb74299bba437fb95 Mon Sep 17 00:00:00 2001 From: ahmed sayed Date: Thu, 3 Sep 2020 20:36:23 +0200 Subject: [PATCH] add ability to filter by nested relation scopes --- src/Filters/FiltersScope.php | 12 +++++++++++- tests/FilterTest.php | 15 +++++++++++++++ tests/TestClasses/Models/RelatedModel.php | 6 ++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/Filters/FiltersScope.php b/src/Filters/FiltersScope.php index a04402b6..0d1e67c0 100644 --- a/src/Filters/FiltersScope.php +++ b/src/Filters/FiltersScope.php @@ -14,11 +14,21 @@ class FiltersScope implements Filter { public function __invoke(Builder $query, $values, string $property): Builder { - $scope = Str::camel($property); + $propertyParts = Str::of($property)->explode('.'); + + $scope = Str::camel($propertyParts->pop()); $values = array_values(Arr::wrap($values)); $values = $this->resolveParameters($query, $values, $scope); + $relation = $propertyParts->implode('.'); + + if ($relation) { + return $query->whereHas($relation, function (Builder $query) use ($scope, $values) { + return $query->$scope(...$values); + }); + } + return $query->$scope(...$values); } diff --git a/tests/FilterTest.php b/tests/FilterTest.php index e4d934ad..157abc80 100644 --- a/tests/FilterTest.php +++ b/tests/FilterTest.php @@ -200,6 +200,21 @@ public function it_can_filter_results_by_scope() $this->assertCount(1, $modelsResult); } + /** @test */ + public function it_can_filter_results_by_nested_relation_scope() + { + $testModel = TestModel::create(['name' => 'John Testing Doe']); + + $testModel->relatedModels()->create(['name' => 'John\'s Post']); + + $modelsResult = $this + ->createQueryFromFilterRequest(['relatedModels.named' => 'John\'s Post']) + ->allowedFilters(AllowedFilter::scope('relatedModels.named')) + ->get(); + + $this->assertCount(1, $modelsResult); + } + /** @test */ public function it_can_filter_results_by_type_hinted_scope() { diff --git a/tests/TestClasses/Models/RelatedModel.php b/tests/TestClasses/Models/RelatedModel.php index 7d511c5b..bc612e98 100644 --- a/tests/TestClasses/Models/RelatedModel.php +++ b/tests/TestClasses/Models/RelatedModel.php @@ -2,6 +2,7 @@ namespace Spatie\QueryBuilder\Tests\TestClasses\Models; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -21,4 +22,9 @@ public function nestedRelatedModels(): HasMany { return $this->hasMany(NestedRelatedModel::class); } + + public function scopeNamed(Builder $query, string $name): Builder + { + return $query->where('name', $name); + } }