Skip to content

Commit

Permalink
- Illuminate\Database\Query::whereIntegerInRaw() now properly handles…
Browse files Browse the repository at this point in the history
… BackedEnums (#49787)

- Illuminate\Database\Eloquent\Relations\BelongsTo::getForeignKeyFrom() handles BackedEnums properly

See #49735

Co-authored-by: Saad <[email protected]>
  • Loading branch information
saadsidqui and saadsidqui authored Apr 15, 2024
1 parent c9cc180 commit 192f909
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 6 deletions.
5 changes: 4 additions & 1 deletion src/Illuminate/Database/Eloquent/Relations/BelongsTo.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Illuminate/Database/Query/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -1207,7 +1207,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');
Expand Down
40 changes: 39 additions & 1 deletion tests/Database/DatabaseEloquentBelongsToTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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;
Expand All @@ -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()
Expand Down Expand Up @@ -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,
];
}
10 changes: 7 additions & 3 deletions tests/Database/DatabaseQueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1039,17 +1040,20 @@ 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();
$builder->select('*')->from('users')->whereIntegerInRaw('id', [
['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());
}

Expand Down
8 changes: 8 additions & 0 deletions tests/Database/Fixtures/Enums/Bar.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Illuminate\Tests\Database\Fixtures\Enums;

enum Bar: int
{
case FOO = 5;
}

0 comments on commit 192f909

Please sign in to comment.