Skip to content

Commit 15519f5

Browse files
authored
Merge pull request #3035 from OzanKurt/patch-7
feat: Ability to use deep relations for searching
2 parents 6662926 + 01b7cb4 commit 15519f5

File tree

2 files changed

+94
-2
lines changed

2 files changed

+94
-2
lines changed

src/EloquentDataTable.php

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,35 @@ protected function getPrimaryKeyName(): string
8181
/**
8282
* @inheritDoc
8383
*/
84-
protected function compileQuerySearch($query, string $column, string $keyword, string $boolean = 'or'): void
84+
protected function compileQuerySearch($query, string $column, string $keyword, string $boolean = 'or', bool $nested = false): void
8585
{
86+
if (substr_count($column, '.') > 1) {
87+
$parts = explode('.', $column);
88+
$firstRelation = array_shift($parts);
89+
$column = implode('.', $parts);
90+
91+
if ($this->isMorphRelation($firstRelation)) {
92+
$query->{$boolean.'WhereHasMorph'}(
93+
$firstRelation,
94+
'*',
95+
function (EloquentBuilder $query) use ($column, $keyword) {
96+
parent::compileQuerySearch($query, $column, $keyword, '');
97+
}
98+
);
99+
} else {
100+
$query->{$boolean.'WhereHas'}($firstRelation, function (EloquentBuilder $query) use ($column, $keyword) {
101+
self::compileQuerySearch($query, $column, $keyword, '', true);
102+
});
103+
}
104+
105+
return;
106+
}
107+
86108
$parts = explode('.', $column);
87109
$newColumn = array_pop($parts);
88110
$relation = implode('.', $parts);
89111

90-
if ($this->isNotEagerLoaded($relation)) {
112+
if (!$nested && $this->isNotEagerLoaded($relation)) {
91113
parent::compileQuerySearch($query, $column, $keyword, $boolean);
92114

93115
return;
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
namespace Yajra\DataTables\Tests\Integration;
4+
5+
use Yajra\DataTables\DataTables;
6+
use Yajra\DataTables\Tests\TestCase;
7+
use Yajra\DataTables\Tests\Models\Post;
8+
use Yajra\DataTables\Tests\Models\User;
9+
use Illuminate\Foundation\Testing\DatabaseTransactions;
10+
11+
class DeepRelationTest extends TestCase
12+
{
13+
use DatabaseTransactions;
14+
15+
/** @test */
16+
public function it_returns_all_records_with_the_relation_when_called_without_parameters()
17+
{
18+
$response = $this->getJsonResponse();
19+
$response->assertJson([
20+
'draw' => 0,
21+
'recordsTotal' => 60,
22+
'recordsFiltered' => 60,
23+
]);
24+
25+
$this->assertCount(60, $response->json()['data']);
26+
}
27+
28+
/** @test */
29+
public function it_can_perform_global_search_on_the_relation()
30+
{
31+
$response = $this->getJsonResponse([
32+
'search' => ['value' => '[email protected]'],
33+
]);
34+
35+
$response->assertJson([
36+
'draw' => 0,
37+
'recordsTotal' => 60,
38+
'recordsFiltered' => 3,
39+
]);
40+
41+
$this->assertCount(3, $response->json()['data']);
42+
}
43+
44+
protected function setUp(): void
45+
{
46+
parent::setUp();
47+
48+
$this->app['router']->get('/relations/deep', function (DataTables $datatables) {
49+
$query = Post::with('user.roles')->select('posts.*');
50+
51+
return $datatables
52+
->eloquent($query)
53+
->toJson();
54+
});
55+
}
56+
57+
protected function getJsonResponse(array $params = [])
58+
{
59+
$data = [
60+
'columns' => [
61+
['data' => 'user.roles.role', 'name' => 'user.roles.role', 'searchable' => 'true', 'orderable' => 'true'],
62+
['data' => 'user.name', 'name' => 'user.name', 'searchable' => 'true', 'orderable' => 'true'],
63+
['data' => 'user.email', 'name' => 'user.email', 'searchable' => 'true', 'orderable' => 'true'],
64+
['data' => 'title', 'name' => 'title', 'searchable' => 'true', 'orderable' => 'true'],
65+
],
66+
];
67+
68+
return $this->call('GET', '/relations/deep', array_merge($data, $params));
69+
}
70+
}

0 commit comments

Comments
 (0)