Skip to content

Commit 8378ab2

Browse files
authored
[10.x] Fix whereHasMorph() with nullable morphs (#48903)
* Support nullable morphs in whereHasMorph() * Expand the whereHasMorph with nullable morph by using a sub condition * Support nullable morphs in whereDoesntHaveMorph and orWhereHasMorph * Fix testOrWhereHasMorphWithWildcardAndOnlyNullMorphTypes so there are no morph types in the database
1 parent 0fde761 commit 8378ab2

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,10 @@ public function hasMorph($relation, $types, $operator = '>=', $count = 1, $boole
230230
$types = $this->model->newModelQuery()->distinct()->pluck($relation->getMorphType())->filter()->all();
231231
}
232232

233+
if (empty($types)) {
234+
return $this->where(new Expression('0'), $operator, $count, $boolean);
235+
}
236+
233237
foreach ($types as &$type) {
234238
$type = Relation::getMorphedModel($type) ?? $type;
235239
}

tests/Integration/Database/EloquentWhereHasMorphTest.php

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ protected function defineDatabaseMigrationsAfterDatabaseRefreshed()
2727

2828
Schema::create('comments', function (Blueprint $table) {
2929
$table->increments('id');
30-
$table->morphs('commentable');
30+
$table->nullableMorphs('commentable');
3131
$table->softDeletes();
3232
});
3333

@@ -41,6 +41,8 @@ protected function defineDatabaseMigrationsAfterDatabaseRefreshed()
4141
$models[] = Video::create(['title' => 'foo']);
4242
$models[] = Video::create(['title' => 'bar']);
4343
$models[] = Video::create(['title' => 'baz']);
44+
$models[] = null; // deleted
45+
$models[] = null; // deleted
4446

4547
foreach ($models as $model) {
4648
(new Comment)->commentable()->associate($model)->save();
@@ -103,6 +105,19 @@ public function testWhereHasMorphWithWildcardAndMorphMap()
103105
}
104106
}
105107

108+
public function testWhereHasMorphWithWildcardAndOnlyNullMorphTypes()
109+
{
110+
Comment::whereNotNull('commentable_type')->forceDelete();
111+
112+
$comments = Comment::query()
113+
->whereHasMorph('commentable', '*', function (Builder $query) {
114+
$query->where('title', 'foo');
115+
})
116+
->orderBy('id')->get();
117+
118+
$this->assertEmpty($comments->pluck('id')->all());
119+
}
120+
106121
public function testWhereHasMorphWithRelationConstraint()
107122
{
108123
$comments = Comment::whereHasMorph('commentableWithConstraint', Video::class, function (Builder $query) {
@@ -190,6 +205,18 @@ public function testOrWhereHasMorph()
190205
$this->assertEquals([1, 4], $comments->pluck('id')->all());
191206
}
192207

208+
public function testOrWhereHasMorphWithWildcardAndOnlyNullMorphTypes()
209+
{
210+
Comment::whereNotNull('commentable_type')->forceDelete();
211+
212+
$comments = Comment::where('id', 7)
213+
->orWhereHasMorph('commentable', '*', function (Builder $query) {
214+
$query->where('title', 'foo');
215+
})->orderBy('id')->get();
216+
217+
$this->assertEquals([7], $comments->pluck('id')->all());
218+
}
219+
193220
public function testWhereDoesntHaveMorph()
194221
{
195222
$comments = Comment::whereDoesntHaveMorph('commentable', Post::class, function (Builder $query) {
@@ -199,6 +226,17 @@ public function testWhereDoesntHaveMorph()
199226
$this->assertEquals([2, 3], $comments->pluck('id')->all());
200227
}
201228

229+
public function testWhereDoesntHaveMorphWithWildcardAndOnlyNullMorphTypes()
230+
{
231+
Comment::whereNotNull('commentable_type')->forceDelete();
232+
233+
$comments = Comment::whereDoesntHaveMorph('commentable', [], function (Builder $query) {
234+
$query->where('title', 'foo');
235+
})->orderBy('id')->get();
236+
237+
$this->assertEquals([7, 8], $comments->pluck('id')->all());
238+
}
239+
202240
public function testOrWhereDoesntHaveMorph()
203241
{
204242
$comments = Comment::where('id', 1)

0 commit comments

Comments
 (0)