diff --git a/src/Illuminate/Database/Eloquent/Relations/BelongsTo.php b/src/Illuminate/Database/Eloquent/Relations/BelongsTo.php index 8bde76a0c388..112a0edba022 100755 --- a/src/Illuminate/Database/Eloquent/Relations/BelongsTo.php +++ b/src/Illuminate/Database/Eloquent/Relations/BelongsTo.php @@ -2,6 +2,7 @@ namespace Illuminate\Database\Eloquent\Relations; +use BackedEnum; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; @@ -375,7 +376,9 @@ protected function getRelatedKeyFrom(Model $model) */ protected function getForeignKeyFrom(Model $model) { - return $model->{$this->foreignKey}; + $foreignKey = $model->{$this->foreignKey}; + + return $foreignKey instanceof BackedEnum ? $foreignKey->value : $foreignKey; } /** diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index 62abc80023c8..546624662f34 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -1161,7 +1161,7 @@ public function whereIntegerInRaw($column, $values, $boolean = 'and', $not = fal $values = Arr::flatten($values); foreach ($values as &$value) { - $value = (int) $value; + $value = (int) ($value instanceof BackedEnum ? $value->value : $value); } $this->wheres[] = compact('type', 'column', 'values', 'boolean'); diff --git a/tests/Database/DatabaseEloquentBelongsToTest.php b/tests/Database/DatabaseEloquentBelongsToTest.php index 0c392e704412..1ace437a4346 100755 --- a/tests/Database/DatabaseEloquentBelongsToTest.php +++ b/tests/Database/DatabaseEloquentBelongsToTest.php @@ -6,6 +6,7 @@ use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Tests\Database\Fixtures\Enums\Bar; use Mockery as m; use PHPUnit\Framework\TestCase; @@ -85,6 +86,16 @@ public function testIdsInEagerConstraintsCanBeZero() $relation->addEagerConstraints($models); } + public function testIdsInEagerConstraintsCanBeBackedEnum() + { + $relation = $this->getRelation(); + $relation->getRelated()->shouldReceive('getKeyName')->andReturn('id'); + $relation->getRelated()->shouldReceive('getKeyType')->andReturn('int'); + $relation->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('relation.id', [5, 'foreign.value']); + $models = [new EloquentBelongsToModelStub, new EloquentBelongsToModelStubWithBackedEnumCast]; + $relation->addEagerConstraints($models); + } + public function testRelationIsProperlyInitialized() { $relation = $this->getRelation(); @@ -119,6 +130,15 @@ public function __toString() } }; + $result4 = new class extends Model + { + protected $casts = [ + 'id' => Bar::class, + ]; + + protected $attributes = ['id' => 5]; + }; + $model1 = new EloquentBelongsToModelStub; $model1->foreign_key = 1; $model2 = new EloquentBelongsToModelStub; @@ -131,11 +151,18 @@ public function __toString() return '3'; } }; - $models = $relation->match([$model1, $model2, $model3], new Collection([$result1, $result2, $result3]), 'foo'); + $model4 = new EloquentBelongsToModelStub; + $model4->foreign_key = 5; + $models = $relation->match( + [$model1, $model2, $model3, $model4], + new Collection([$result1, $result2, $result3, $result4]), + 'foo' + ); $this->assertEquals(1, $models[0]->foo->getAttribute('id')); $this->assertEquals(2, $models[1]->foo->getAttribute('id')); $this->assertSame('3', (string) $models[2]->foo->getAttribute('id')); + $this->assertEquals(5, $models[3]->foo->getAttribute('id')->value); } public function testAssociateMethodSetsForeignKeyOnModel() @@ -403,3 +430,14 @@ class MissingEloquentBelongsToModelStub extends Model { public $foreign_key; } + +class EloquentBelongsToModelStubWithBackedEnumCast extends Model +{ + protected $casts = [ + 'foreign_key' => Bar::class, + ]; + + public $attributes = [ + 'foreign_key' => 5, + ]; +} diff --git a/tests/Database/DatabaseQueryBuilderTest.php b/tests/Database/DatabaseQueryBuilderTest.php index 011e22c99afb..5be1c956db9b 100755 --- a/tests/Database/DatabaseQueryBuilderTest.php +++ b/tests/Database/DatabaseQueryBuilderTest.php @@ -23,6 +23,7 @@ use Illuminate\Pagination\Cursor; use Illuminate\Pagination\CursorPaginator; use Illuminate\Pagination\LengthAwarePaginator; +use Illuminate\Tests\Database\Fixtures\Enums\Bar; use InvalidArgumentException; use Mockery as m; use PHPUnit\Framework\TestCase; @@ -1039,8 +1040,10 @@ public function testEmptyWhereNotIns() public function testWhereIntegerInRaw() { $builder = $this->getBuilder(); - $builder->select('*')->from('users')->whereIntegerInRaw('id', ['1a', 2]); - $this->assertSame('select * from "users" where "id" in (1, 2)', $builder->toSql()); + $builder->select('*')->from('users')->whereIntegerInRaw('id', [ + '1a', 2, Bar::FOO, + ]); + $this->assertSame('select * from "users" where "id" in (1, 2, 5)', $builder->toSql()); $this->assertEquals([], $builder->getBindings()); $builder = $this->getBuilder(); @@ -1048,8 +1051,9 @@ public function testWhereIntegerInRaw() ['id' => '1a'], ['id' => 2], ['any' => '3'], + ['id' => Bar::FOO], ]); - $this->assertSame('select * from "users" where "id" in (1, 2, 3)', $builder->toSql()); + $this->assertSame('select * from "users" where "id" in (1, 2, 3, 5)', $builder->toSql()); $this->assertEquals([], $builder->getBindings()); } diff --git a/tests/Database/Fixtures/Enums/Bar.php b/tests/Database/Fixtures/Enums/Bar.php new file mode 100644 index 000000000000..bc019a9be02c --- /dev/null +++ b/tests/Database/Fixtures/Enums/Bar.php @@ -0,0 +1,8 @@ +