Skip to content

Commit

Permalink
Relations search unify (#61)
Browse files Browse the repository at this point in the history
* Consolidate relations search

Consolidate relations search, enclose in where statement to keep relation join correct.
Add tests to test relations parts

* Apply fixes from StyleCI

---------

Co-authored-by: StyleCI Bot <bot@styleci.io>
  • Loading branch information
ngaspari and StyleCIBot authored Sep 19, 2024
1 parent 2ce442b commit 259e62b
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 12 deletions.
11 changes: 0 additions & 11 deletions src/RequestParameters/SearchParameter.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/SearchCallbacks/AbstractCallback.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
}
Expand Down
6 changes: 6 additions & 0 deletions tests/TestModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
18 changes: 18 additions & 0 deletions tests/TestRelationOneModel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Asseco\JsonQueryBuilder\Tests;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class TestRelationOneModel extends Model
{
protected $table = 'test_relation_one';

public function testModel(): BelongsTo
{
return $this->belongsTo(TestModel::class);
}
}
54 changes: 54 additions & 0 deletions tests/Unit/RequestParameters/SearchParameterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

0 comments on commit 259e62b

Please sign in to comment.