Skip to content

Commit 52a1282

Browse files
authored
Added support for powerJoinHas with MorphTo relationships (#162)
* Added support for powerJoinHas with MorphTo relationships * Readme addition
1 parent 2cb2d87 commit 52a1282

File tree

4 files changed

+45
-10
lines changed

4 files changed

+45
-10
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,8 @@ There's, though, a gotcha here. Your global scope **cannot** type-hint the `Eloq
278278

279279
This packages implements the same functionality, but instead of using the `where exists` syntax, it uses **joins**. Below, you can see the methods this package implements and also the Laravel equivalent.
280280

281+
Please note that although the methods are similar, you will not always get the same results when using joins, depending on the context of your query. You should be aware of the differences between querying the data with `where exists` vs `joins`.
282+
281283
**Laravel Native Methods**
282284

283285
``` php

src/Mixins/JoinRelationship.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ public function orderByLeftPowerJoinsMax(): Closure
461461
*/
462462
public function powerJoinHas(): Closure
463463
{
464-
return function ($relation, $operator = '>=', $count = 1, $boolean = 'and', $callback = null): static {
464+
return function ($relation, $operator = '>=', $count = 1, $boolean = 'and', $callback = null, string $morphable = null): static {
465465
if (is_null($this->getSelect())) {
466466
$this->select(sprintf('%s.*', $this->getModel()->getTable()));
467467
}
@@ -479,9 +479,8 @@ public function powerJoinHas(): Closure
479479

480480
$relation = $this->getRelationWithoutConstraintsProxy($relation);
481481
}
482-
483-
$relation->performJoinForEloquentPowerJoins($this, 'leftPowerJoin', $callback);
484-
$relation->performHavingForEloquentPowerJoins($this, $operator, $count);
482+
$relation->performJoinForEloquentPowerJoins($this, 'leftPowerJoin', $callback, morphable: $morphable);
483+
$relation->performHavingForEloquentPowerJoins($this, $operator, $count, morphable: $morphable);
485484
return $this;
486485
};
487486
}

src/Mixins/RelationshipsExtraMethods.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -386,10 +386,18 @@ protected function performJoinForEloquentPowerJoinsForHasManyThrough()
386386
*/
387387
public function performHavingForEloquentPowerJoins()
388388
{
389-
return function ($builder, $operator, $count) {
390-
$builder
391-
->selectRaw(sprintf('count(%s) as %s_count', $this->query->getModel()->getQualifiedKeyName(), $this->query->getModel()->getTable()))
392-
->havingRaw(sprintf('count(%s) %s %d', $this->query->getModel()->getQualifiedKeyName(), $operator, $count));
389+
return function ($builder, $operator, $count, string $morphable = null) {
390+
if ($morphable) {
391+
$modelInstance = new $morphable;
392+
393+
$builder
394+
->selectRaw(sprintf('count(%s) as %s_count', $modelInstance->getQualifiedKeyName(), $modelInstance->getTable()))
395+
->havingRaw(sprintf('count(%s) %s %d', $modelInstance->getQualifiedKeyName(), $operator, $count));
396+
} else {
397+
$builder
398+
->selectRaw(sprintf('count(%s) as %s_count', $this->query->getModel()->getQualifiedKeyName(), $this->query->getModel()->getTable()))
399+
->havingRaw(sprintf('count(%s) %s %d', $this->query->getModel()->getQualifiedKeyName(), $operator, $count));
400+
}
393401
};
394402
}
395403

tests/PowerJoinHasTest.php

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
namespace Kirschbaum\PowerJoins\Tests;
44

5-
use Kirschbaum\PowerJoins\Tests\Models\Comment;
6-
use Kirschbaum\PowerJoins\Tests\Models\Group;
75
use Kirschbaum\PowerJoins\Tests\Models\Post;
86
use Kirschbaum\PowerJoins\Tests\Models\User;
7+
use Kirschbaum\PowerJoins\Tests\Models\Group;
8+
use Kirschbaum\PowerJoins\Tests\Models\Image;
9+
use Kirschbaum\PowerJoins\Tests\Models\Comment;
910

1011
class PowerJoinHasTest extends TestCase
1112
{
@@ -171,4 +172,29 @@ public function test_where_has_with_joins_on_belongs_to_many_relationship()
171172
);
172173
$this->assertCount(1, $powerJoinQuery->get());
173174
}
175+
176+
public function test_power_join_has_with_morph_to()
177+
{
178+
$post = factory(Post::class)->state('published')->create();
179+
$postImage = factory(Image::class)->state('owner:post')->create(['imageable_id' => $post->id]);
180+
$user = factory(Post::class)->create();
181+
$userImage = factory(Image::class)->state('owner:user')->create(['imageable_id' => $user->id]);
182+
183+
$postImagesQueried = Image::query()
184+
->powerJoinHas('imageable', morphable: Post::class)
185+
->get();
186+
187+
$userImagesQueried = Image::query()
188+
->powerJoinHas('imageable', morphable: User::class)
189+
->get();
190+
191+
$this->assertCount(1, $postImagesQueried);
192+
$this->assertCount(1, Image::powerJoinHas('imageable', morphable: Post::class, callback: fn ($query) => $query->where('posts.published', true))->get());
193+
$this->assertCount(0, Image::powerJoinHas('imageable', morphable: Post::class, callback: fn ($query) => $query->where('posts.published', false))->get());
194+
$this->assertCount(0, Image::powerJoinHas('imageable', count: 2, morphable: Post::class)->get());
195+
$this->assertTrue($postImage->is($postImagesQueried->sole()));
196+
197+
$this->assertCount(1, $userImagesQueried);
198+
$this->assertTrue($userImage->is($userImagesQueried->sole()));
199+
}
174200
}

0 commit comments

Comments
 (0)