diff --git a/src/Illuminate/Conditionable/Traits/Conditionable.php b/src/Illuminate/Conditionable/Traits/Conditionable.php index 5e3194bbcb6a..fe69c823da28 100644 --- a/src/Illuminate/Conditionable/Traits/Conditionable.php +++ b/src/Illuminate/Conditionable/Traits/Conditionable.php @@ -31,9 +31,16 @@ public function when($value = null, ?callable $callback = null, ?callable $defau } if ($value) { - return $callback($this, $value) ?? $this; + $result = $callback($this, $value) ?? $this; } elseif ($default) { - return $default($this, $value) ?? $this; + $result = $default($this, $value) ?? $this; + } else { + return $this; + } + + if ($this instanceof \Illuminate\Database\Eloquent\Relations\BelongsToMany && $result instanceof \Illuminate\Database\Eloquent\Builder) { + $this->query = $result; + return $this; } return $this; diff --git a/src/Illuminate/Database/Eloquent/Relations/Relation.php b/src/Illuminate/Database/Eloquent/Relations/Relation.php index eefc94775359..c5f3f27cef2e 100755 --- a/src/Illuminate/Database/Eloquent/Relations/Relation.php +++ b/src/Illuminate/Database/Eloquent/Relations/Relation.php @@ -10,7 +10,9 @@ use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Database\MultipleRecordsFoundException; use Illuminate\Database\Query\Expression; +use Illuminate\Support\Traits\Conditionable; use Illuminate\Support\Collection as BaseCollection; + use Illuminate\Support\Traits\ForwardsCalls; use Illuminate\Support\Traits\Macroable; @@ -23,7 +25,7 @@ */ abstract class Relation implements BuilderContract { - use ForwardsCalls, Macroable { + use ForwardsCalls, Conditionable, Macroable { Macroable::__call as macroCall; } diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index 4e7067a1f3aa..83c084b29e11 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -22,6 +22,7 @@ use Illuminate\Support\Collection; use Illuminate\Support\LazyCollection; use Illuminate\Support\Str; +use Illuminate\Support\Traits\Conditionable; use Illuminate\Support\Traits\ForwardsCalls; use Illuminate\Support\Traits\Macroable; use InvalidArgumentException; @@ -34,7 +35,7 @@ class Builder implements BuilderContract { /** @use \Illuminate\Database\Concerns\BuildsQueries */ - use BuildsQueries, ExplainsQueries, ForwardsCalls, Macroable { + use BuildsQueries, ExplainsQueries, ForwardsCalls, Conditionable, Macroable { __call as macroCall; } diff --git a/tests/Integration/Database/EloquentModelTest.php b/tests/Integration/Database/EloquentModelTest.php index d4ad6c207437..b0bc89654f3c 100644 --- a/tests/Integration/Database/EloquentModelTest.php +++ b/tests/Integration/Database/EloquentModelTest.php @@ -2,7 +2,9 @@ namespace Illuminate\Tests\Integration\Database; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Schema; @@ -22,6 +24,13 @@ protected function afterRefreshingDatabase() $table->string('name'); $table->string('title'); }); + + Schema::create('test_model1_test_model2', function (Blueprint $table) { + $table->increments('id'); + $table->integer('test_model1_id'); + $table->integer('test_model2_id'); + $table->timestamp('updated_at')->nullable(); + }); } public function testUserCanUpdateNullableDate() @@ -126,6 +135,45 @@ public function testInsertRecordWithReservedWordFieldName() 'analyze' => true, ]); } + + public function testBelongsToManyWhenMethodMaintainsRelationInstance() + { + $model1 = TestModel1::create(['nullable_date' => now()]); + $model2 = TestModel2::create([ + 'name' => 'Test Name', + 'title' => 'Test Title', + ]); + + // Create the pivot record + $model1->testRelation1()->attach($model2->id, [ + 'updated_at' => '2023-01-01 00:00:00', + ]); + + $query = $model1->testRelation1() + ->when(true, function ($query) { + $this->assertInstanceOf( + BelongsToMany::class, + $query, + 'Query should be instance of BelongsToMany within when callback' + ); + + return $query->wherePivotBetween( + 'updated_at', + ['2022-01-01 00:00:00', '2024-01-01 00:00:00'] + ); + }); + + $this->assertInstanceOf( + BelongsToMany::class, + $query, + 'Query should remain instance of BelongsToMany after when method' + ); + + $result = $query->get(); + + $this->assertInstanceOf(Collection::class, $result); + $this->assertCount(1, $result); + } } class TestModel1 extends Model @@ -134,6 +182,12 @@ class TestModel1 extends Model public $timestamps = false; protected $guarded = []; protected $casts = ['nullable_date' => 'datetime']; + + public function testRelation1() + { + return $this->belongsToMany(TestModel2::class) + ->withPivot('updated_at'); + } } class TestModel2 extends Model