Skip to content

Commit 294661d

Browse files
[10.x] Allow utilising withTrashed(), withoutTrashed() and onlyTrashed() on MorphTo relationship even without SoftDeletes Model (#47880)
* wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * Update tests/Integration/Database/EloquentMorphEagerLoadingTest.php * formatting --------- Signed-off-by: Mior Muhammad Zaki <[email protected]> Co-authored-by: Taylor Otwell <[email protected]>
1 parent 14e8ee4 commit 294661d

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

src/Illuminate/Database/Eloquent/Relations/MorphTo.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,57 @@ public function constrain(array $callbacks)
350350
return $this;
351351
}
352352

353+
/**
354+
* Indicate that soft deleted models should be included in the results.
355+
*
356+
* @return $this
357+
*/
358+
public function withTrashed()
359+
{
360+
$callback = fn ($query) => $query->hasMacro('withTrashed') ? $query->withTrashed() : $query;
361+
362+
$this->macroBuffer[] = [
363+
'method' => 'when',
364+
'parameters' => [true, $callback],
365+
];
366+
367+
return $this->when(true, $callback);
368+
}
369+
370+
/**
371+
* Indicate that soft deleted models should not be included in the results.
372+
*
373+
* @return $this
374+
*/
375+
public function withoutTrashed()
376+
{
377+
$callback = fn ($query) => $query->hasMacro('withoutTrashed') ? $query->withoutTrashed() : $query;
378+
379+
$this->macroBuffer[] = [
380+
'method' => 'when',
381+
'parameters' => [true, $callback],
382+
];
383+
384+
return $this->when(true, $callback);
385+
}
386+
387+
/**
388+
* Indicate that only soft deleted models should be included in the results.
389+
*
390+
* @return $this
391+
*/
392+
public function onlyTrashed()
393+
{
394+
$callback = fn ($query) => $query->hasMacro('onlyTrashed') ? $query->onlyTrashed() : $query;
395+
396+
$this->macroBuffer[] = [
397+
'method' => 'when',
398+
'parameters' => [true, $callback],
399+
];
400+
401+
return $this->when(true, $callback);
402+
}
403+
353404
/**
354405
* Replay stored macro calls on the actual related instance.
355406
*

tests/Integration/Database/EloquentMorphEagerLoadingTest.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Illuminate\Database\Eloquent\Model;
66
use Illuminate\Database\Eloquent\Relations\MorphTo;
7+
use Illuminate\Database\Eloquent\SoftDeletes;
78
use Illuminate\Database\Schema\Blueprint;
89
use Illuminate\Support\Facades\Schema;
910
use Illuminate\Tests\Integration\Database\DatabaseTestCase;
@@ -14,6 +15,7 @@ protected function defineDatabaseMigrationsAfterDatabaseRefreshed()
1415
{
1516
Schema::create('users', function (Blueprint $table) {
1617
$table->increments('id');
18+
$table->softDeletes();
1719
});
1820

1921
Schema::create('posts', function (Blueprint $table) {
@@ -25,20 +27,30 @@ protected function defineDatabaseMigrationsAfterDatabaseRefreshed()
2527
$table->increments('video_id');
2628
});
2729

30+
Schema::create('actions', function (Blueprint $table) {
31+
$table->increments('id');
32+
$table->string('target_type');
33+
$table->integer('target_id');
34+
});
35+
2836
Schema::create('comments', function (Blueprint $table) {
2937
$table->increments('id');
3038
$table->string('commentable_type');
3139
$table->integer('commentable_id');
3240
});
3341

3442
$user = User::create();
43+
$user2 = User::forceCreate(['deleted_at' => now()]);
3544

3645
$post = tap((new Post)->user()->associate($user))->save();
3746

3847
$video = Video::create();
3948

4049
(new Comment)->commentable()->associate($post)->save();
4150
(new Comment)->commentable()->associate($video)->save();
51+
52+
(new Action)->target()->associate($video)->save();
53+
(new Action)->target()->associate($user2)->save();
4254
}
4355

4456
public function testWithMorphLoading()
@@ -49,9 +61,13 @@ public function testWithMorphLoading()
4961
}])
5062
->get();
5163

64+
$this->assertCount(2, $comments);
65+
5266
$this->assertTrue($comments[0]->relationLoaded('commentable'));
67+
$this->assertInstanceOf(Post::class, $comments[0]->getRelation('commentable'));
5368
$this->assertTrue($comments[0]->commentable->relationLoaded('user'));
5469
$this->assertTrue($comments[1]->relationLoaded('commentable'));
70+
$this->assertInstanceOf(Video::class, $comments[1]->getRelation('commentable'));
5571
}
5672

5773
public function testWithMorphLoadingWithSingleRelation()
@@ -65,6 +81,30 @@ public function testWithMorphLoadingWithSingleRelation()
6581
$this->assertTrue($comments[0]->relationLoaded('commentable'));
6682
$this->assertTrue($comments[0]->commentable->relationLoaded('user'));
6783
}
84+
85+
public function testMorphLoadingMixedWithTrashedRelations()
86+
{
87+
$action = Action::query()
88+
->with('target')
89+
->get();
90+
91+
$this->assertCount(2, $action);
92+
93+
$this->assertTrue($action[0]->relationLoaded('target'));
94+
$this->assertInstanceOf(Video::class, $action[0]->getRelation('target'));
95+
$this->assertTrue($action[1]->relationLoaded('target'));
96+
$this->assertInstanceOf(User::class, $action[1]->getRelation('target'));
97+
}
98+
}
99+
100+
class Action extends Model
101+
{
102+
public $timestamps = false;
103+
104+
public function target()
105+
{
106+
return $this->morphTo()->withTrashed();
107+
}
68108
}
69109

70110
class Comment extends Model
@@ -90,6 +130,8 @@ public function user()
90130

91131
class User extends Model
92132
{
133+
use SoftDeletes;
134+
93135
public $timestamps = false;
94136
}
95137

0 commit comments

Comments
 (0)