Skip to content

Commit 259e62b

Browse files
ngaspariStyleCIBot
andauthored
Relations search unify (#61)
* 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>
1 parent 2ce442b commit 259e62b

File tree

5 files changed

+83
-12
lines changed

5 files changed

+83
-12
lines changed

src/RequestParameters/SearchParameter.php

-11
Original file line numberDiff line numberDiff line change
@@ -91,17 +91,6 @@ protected function makeQuery(Builder $builder, array $arguments, string $boolOpe
9191
continue;
9292
}
9393

94-
if ($this->isRelationSearch($key) && !str_contains($key, '!')) {
95-
// relation search
96-
[$rel, $attr] = explode(self::RELATION_SEPARATOR, $key, 2);
97-
98-
$builder->whereHas(Str::camel($rel), function ($query) use ($attr, $value, $functionName) {
99-
$this->makeSingleQuery($functionName, $query, $attr, $value);
100-
});
101-
102-
continue;
103-
}
104-
10594
$this->makeSingleQuery($functionName, $builder, $key, $value);
10695
}
10796
}

src/SearchCallbacks/AbstractCallback.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,11 @@ protected function appendRelations(Builder $builder, string $column, Categorized
9292
return;
9393
}
9494

95-
$this->execute($builder, $relatedColumns, $values);
95+
// $this->execute($builder, $relatedColumns, $values);
96+
// need to group those wheres statements....otherwise, there will be OR statement added, and relation would be "broken"
97+
$builder->where(function ($builder) use ($relatedColumns, $values) {
98+
$this->execute($builder, $relatedColumns, $values);
99+
});
96100
$this->checkExecuteForCustomfieldsParameter($builder);
97101
});
98102
}

tests/TestModel.php

+6
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,14 @@
55
namespace Asseco\JsonQueryBuilder\Tests;
66

77
use Illuminate\Database\Eloquent\Model;
8+
use Illuminate\Database\Eloquent\Relations\HasMany;
89

910
class TestModel extends Model
1011
{
1112
protected $table = 'test';
13+
14+
public function relationsOne(): HasMany
15+
{
16+
return $this->hasMany(TestRelationOneModel::class);
17+
}
1218
}

tests/TestRelationOneModel.php

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Asseco\JsonQueryBuilder\Tests;
6+
7+
use Illuminate\Database\Eloquent\Model;
8+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
9+
10+
class TestRelationOneModel extends Model
11+
{
12+
protected $table = 'test_relation_one';
13+
14+
public function testModel(): BelongsTo
15+
{
16+
return $this->belongsTo(TestModel::class);
17+
}
18+
}

tests/Unit/RequestParameters/SearchParameterTest.php

+54
Original file line numberDiff line numberDiff line change
@@ -215,4 +215,58 @@ public function produces_not_between_query()
215215

216216
$this->assertEquals($query, $this->builder->toSql());
217217
}
218+
219+
/** @test */
220+
public function produces_correct_relations_query_one()
221+
{
222+
$arguments = [
223+
'relationsOne.attribute1' => '=ABC',
224+
];
225+
226+
$searchParameter = $this->createSearchParameter($arguments);
227+
$searchParameter->run();
228+
229+
$producedSql = $this->builder->toSql();
230+
231+
$query = 'select * from "test" where (((exists (select * from "test_relation_one" where "test"."id" = "test_relation_one"."test_model_id" and ("attribute1" in (?))))))';
232+
233+
$this->assertEquals($query, $producedSql);
234+
}
235+
236+
/** @test */
237+
public function produces_correct_relations_query_for_begins_with()
238+
{
239+
$arguments = [
240+
'relationsOne.attribute1' => 'starts_withABC',
241+
];
242+
243+
$searchParameter = $this->createSearchParameter($arguments);
244+
$searchParameter->run();
245+
246+
$producedSql = $this->builder->toSql();
247+
248+
$query = 'select * from "test" where (((exists (select * from "test_relation_one" where "test"."id" = "test_relation_one"."test_model_id" and ("attribute1" LIKE ?)))))';
249+
250+
$this->assertEquals($query, $producedSql);
251+
}
252+
253+
/** @test */
254+
public function produces_correct_relations_query_for_top_level_or()
255+
{
256+
$arguments = [
257+
'||' => [
258+
'attribute1' => '=AAA',
259+
'relationsOne.attribute1' => 'starts_withBBB',
260+
],
261+
];
262+
263+
$searchParameter = $this->createSearchParameter($arguments);
264+
$searchParameter->run();
265+
266+
$producedSql = $this->builder->toSql();
267+
268+
$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 ?)))))';
269+
270+
$this->assertEquals($query, $producedSql);
271+
}
218272
}

0 commit comments

Comments
 (0)