diff --git a/src/RequestParameters/SearchParameter.php b/src/RequestParameters/SearchParameter.php index f8ec935..cd449e2 100644 --- a/src/RequestParameters/SearchParameter.php +++ b/src/RequestParameters/SearchParameter.php @@ -91,17 +91,6 @@ protected function makeQuery(Builder $builder, array $arguments, string $boolOpe continue; } - if ($this->isRelationSearch($key) && !str_contains($key, '!')) { - // relation search - [$rel, $attr] = explode(self::RELATION_SEPARATOR, $key, 2); - - $builder->whereHas(Str::camel($rel), function ($query) use ($attr, $value, $functionName) { - $this->makeSingleQuery($functionName, $query, $attr, $value); - }); - - continue; - } - $this->makeSingleQuery($functionName, $builder, $key, $value); } } diff --git a/src/SearchCallbacks/AbstractCallback.php b/src/SearchCallbacks/AbstractCallback.php index 70a8089..bbde715 100644 --- a/src/SearchCallbacks/AbstractCallback.php +++ b/src/SearchCallbacks/AbstractCallback.php @@ -92,7 +92,11 @@ protected function appendRelations(Builder $builder, string $column, Categorized return; } - $this->execute($builder, $relatedColumns, $values); + // $this->execute($builder, $relatedColumns, $values); + // need to group those wheres statements....otherwise, there will be OR statement added, and relation would be "broken" + $builder->where(function ($builder) use ($relatedColumns, $values) { + $this->execute($builder, $relatedColumns, $values); + }); $this->checkExecuteForCustomfieldsParameter($builder); }); } diff --git a/tests/TestModel.php b/tests/TestModel.php index 0f84221..43a2fb7 100644 --- a/tests/TestModel.php +++ b/tests/TestModel.php @@ -5,8 +5,14 @@ namespace Asseco\JsonQueryBuilder\Tests; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\HasMany; class TestModel extends Model { protected $table = 'test'; + + public function relationsOne(): HasMany + { + return $this->hasMany(TestRelationOneModel::class); + } } diff --git a/tests/TestRelationOneModel.php b/tests/TestRelationOneModel.php new file mode 100644 index 0000000..a11d981 --- /dev/null +++ b/tests/TestRelationOneModel.php @@ -0,0 +1,18 @@ +belongsTo(TestModel::class); + } +} diff --git a/tests/Unit/RequestParameters/SearchParameterTest.php b/tests/Unit/RequestParameters/SearchParameterTest.php index 6af9b1d..c3c690f 100644 --- a/tests/Unit/RequestParameters/SearchParameterTest.php +++ b/tests/Unit/RequestParameters/SearchParameterTest.php @@ -215,4 +215,58 @@ public function produces_not_between_query() $this->assertEquals($query, $this->builder->toSql()); } + + /** @test */ + public function produces_correct_relations_query_one() + { + $arguments = [ + 'relationsOne.attribute1' => '=ABC', + ]; + + $searchParameter = $this->createSearchParameter($arguments); + $searchParameter->run(); + + $producedSql = $this->builder->toSql(); + + $query = 'select * from "test" where (((exists (select * from "test_relation_one" where "test"."id" = "test_relation_one"."test_model_id" and ("attribute1" in (?))))))'; + + $this->assertEquals($query, $producedSql); + } + + /** @test */ + public function produces_correct_relations_query_for_begins_with() + { + $arguments = [ + 'relationsOne.attribute1' => 'starts_withABC', + ]; + + $searchParameter = $this->createSearchParameter($arguments); + $searchParameter->run(); + + $producedSql = $this->builder->toSql(); + + $query = 'select * from "test" where (((exists (select * from "test_relation_one" where "test"."id" = "test_relation_one"."test_model_id" and ("attribute1" LIKE ?)))))'; + + $this->assertEquals($query, $producedSql); + } + + /** @test */ + public function produces_correct_relations_query_for_top_level_or() + { + $arguments = [ + '||' => [ + 'attribute1' => '=AAA', + 'relationsOne.attribute1' => 'starts_withBBB', + ], + ]; + + $searchParameter = $this->createSearchParameter($arguments); + $searchParameter->run(); + + $producedSql = $this->builder->toSql(); + + $query = 'select * from "test" where ((("attribute1" in (?))) or ((exists (select * from "test_relation_one" where "test"."id" = "test_relation_one"."test_model_id" and ("attribute1" LIKE ?)))))'; + + $this->assertEquals($query, $producedSql); + } }