diff --git a/packages/database/src/BelongsTo.php b/packages/database/src/BelongsTo.php index 8d5a56681..948afd607 100644 --- a/packages/database/src/BelongsTo.php +++ b/packages/database/src/BelongsTo.php @@ -17,6 +17,8 @@ #[Attribute(Attribute::TARGET_PROPERTY)] final class BelongsTo implements Relation { + use HasTableAlias; + public PropertyReflector $property; public string $name { @@ -62,7 +64,7 @@ public function getSelectFields(): ImmutableArray $relationModel = inspect($this->property->getType()->asClass()); $tableReference = $this->isSelfReferencing() ? $this->property->getName() - : $relationModel->getTableName(); + : $this->getTableAlias($relationModel->getTableName()); return $relationModel ->getSelectFields() @@ -79,8 +81,12 @@ public function getJoinStatement(): JoinStatement { $relationModel = inspect($this->property->getType()->asClass()); $ownerModel = inspect($this->property->getClass()); + $tableAlias = $this->getTableAlias($relationModel->getTableName()); - $relationJoin = $this->getRelationJoin($relationModel); + $relationJoin = $this->getRelationJoin( + relationModel: $relationModel, + tableAlias: $tableAlias, + ); $ownerJoin = $this->getOwnerJoin($ownerModel); if ($this->isSelfReferencing()) { @@ -93,21 +99,26 @@ public function getJoinStatement(): JoinStatement )); } + $tableName = $relationModel->getTableName(); + $tableRef = $tableAlias !== $tableName + ? sprintf('%s AS %s', $tableName, $tableAlias) + : $tableName; + // LEFT JOIN authors ON authors.id = books.author_id return new JoinStatement(sprintf( 'LEFT JOIN %s ON %s = %s', - $relationModel->getTableName(), + $tableRef, $relationJoin, $ownerJoin, )); } - private function getRelationJoin(ModelInspector $relationModel): string + private function getRelationJoin(ModelInspector $relationModel, string $tableAlias): string { $relationJoin = $this->relationJoin; $tableReference = $this->isSelfReferencing() ? $this->property->getName() - : $relationModel->getTableName(); + : $tableAlias; if ($relationJoin && ! strpos($relationJoin, '.')) { $relationJoin = sprintf('%s.%s', $tableReference, $relationJoin); diff --git a/packages/database/src/BelongsToMany.php b/packages/database/src/BelongsToMany.php index fa6ee0559..c901c2860 100644 --- a/packages/database/src/BelongsToMany.php +++ b/packages/database/src/BelongsToMany.php @@ -18,6 +18,8 @@ #[Attribute(flags: Attribute::TARGET_PROPERTY)] final class BelongsToMany implements Relation { + use HasTableAlias; + public PropertyReflector $property; public string $name { @@ -54,7 +56,7 @@ public function getSelectFields(): ImmutableArray ->map(map: fn ( $field, ) => new FieldStatement( - field: $targetModel->getTableName() . '.' . $field, + field: "{$this->getTableAlias(tableName: $targetModel->getTableName())}.{$field}", ) ->withAlias( alias: sprintf( @@ -120,7 +122,6 @@ public function getJoinStatement(): JoinStatement ownerModel: $ownerModel, targetModel: $targetModel, ); - return new JoinStatement( statement: sprintf( '%s %s', @@ -131,6 +132,7 @@ public function getJoinStatement(): JoinStatement $this->buildSecondJoin( targetModel: $targetModel, pivotTable: $pivotTable, + tableAlias: $this->getTableAlias(tableName: $targetModel->getTableName()), ), ), ); @@ -174,11 +176,20 @@ private function buildFirstJoin( private function buildSecondJoin( ModelInspector $targetModel, string $pivotTable, + string $tableAlias, ): string { + $tableName = $targetModel->getTableName(); + $tableRef = $tableAlias !== $tableName + ? sprintf('%s AS %s', $tableName, $tableAlias) + : $tableName; + return sprintf( 'LEFT JOIN %s ON %s = %s', - $targetModel->getTableName(), - $this->resolveRelatedRelationJoin(targetModel: $targetModel), + $tableRef, + $this->resolveRelatedRelationJoin( + targetModel: $targetModel, + tableAlias: $tableAlias, + ), $this->resolveRelatedOwnerJoin( targetModel: $targetModel, pivotTable: $pivotTable, @@ -316,7 +327,7 @@ private function resolveRelatedOwnerJoin( /** * PK on target: target.id */ - private function resolveRelatedRelationJoin(ModelInspector $targetModel): string + private function resolveRelatedRelationJoin(ModelInspector $targetModel, string $tableAlias): string { $relatedRelationJoin = $this->relatedRelationJoin; @@ -329,7 +340,7 @@ private function resolveRelatedRelationJoin(ModelInspector $targetModel): string ) { return sprintf( '%s.%s', - $targetModel->getTableName(), + $tableAlias, $relatedRelationJoin, ); } @@ -349,7 +360,7 @@ private function resolveRelatedRelationJoin(ModelInspector $targetModel): string return sprintf( '%s.%s', - $targetModel->getTableName(), + $tableAlias, $primaryKey, ); } diff --git a/packages/database/src/Builder/ModelInspector.php b/packages/database/src/Builder/ModelInspector.php index ef1dd9b05..22a14bc15 100644 --- a/packages/database/src/Builder/ModelInspector.php +++ b/packages/database/src/Builder/ModelInspector.php @@ -606,8 +606,12 @@ public function resolveRelations(string $relationString, string $parent = '', ar $relationModel = inspect($currentRelation); $modelType = $relationModel->getName(); + $fullPath = $parent !== '' + ? "{$parent}.{$currentRelationName}" + : $currentRelationName; + if (in_array($modelType, $visitedPaths, true)) { - return [$currentRelationName => $currentRelation->setParent($parent)]; + return [$fullPath => $currentRelation->setParent($parent)]; } $newRelationString = implode('.', $relationNames); @@ -618,7 +622,7 @@ public function resolveRelations(string $relationString, string $parent = '', ar $currentRelationName, ), '.'); - $relations = [$currentRelationName => $currentRelation]; + $relations = [$fullPath => $currentRelation]; return [ ...$relations, @@ -659,7 +663,10 @@ public function resolveEagerRelations(string $parent = '', array $visitedPaths = continue; } - $relations[$property->getName()] = $currentRelation->setParent($parent); + $fullPath = $parent !== '' + ? "{$parent}.{$currentRelationName}" + : $currentRelationName; + $relations[$fullPath] = $currentRelation->setParent($parent); $newVisitedPaths = [...$visitedPaths, $this->getName()]; foreach ($relationModel->resolveEagerRelations($newParent, $newVisitedPaths) as $name => $nestedEagerRelation) { diff --git a/packages/database/src/HasMany.php b/packages/database/src/HasMany.php index a34948ef4..c39a3465f 100644 --- a/packages/database/src/HasMany.php +++ b/packages/database/src/HasMany.php @@ -17,6 +17,8 @@ #[Attribute(Attribute::TARGET_PROPERTY)] final class HasMany implements Relation { + use HasTableAlias; + public PropertyReflector $property; public string $name { @@ -42,7 +44,7 @@ public function getSelectFields(): ImmutableArray $relationModel = inspect($this->property->getIterableType()->asClass()); $tableReference = $this->isSelfReferencing() ? $this->property->getName() - : $relationModel->getTableName(); + : $this->getTableAlias($relationModel->getTableName()); return $relationModel ->getSelectFields() @@ -87,8 +89,13 @@ public function getJoinStatement(): JoinStatement { $ownerModel = inspect($this->property->getIterableType()->asClass()); $relationModel = inspect($this->property->getClass()); + $tableAlias = $this->getTableAlias($ownerModel->getTableName()); - $ownerJoin = $this->getOwnerJoin($ownerModel, $relationModel); + $ownerJoin = $this->getOwnerJoin( + ownerModel: $ownerModel, + relationModel: $relationModel, + tableAlias: $tableAlias, + ); $relationJoin = $this->getRelationJoin($relationModel); if ($this->isSelfReferencing()) { @@ -101,20 +108,25 @@ public function getJoinStatement(): JoinStatement )); } + $tableName = $ownerModel->getTableName(); + $tableRef = $tableAlias !== $tableName + ? sprintf('%s AS %s', $tableName, $tableAlias) + : $tableName; + return new JoinStatement(sprintf( 'LEFT JOIN %s ON %s = %s', - $ownerModel->getTableName(), + $tableRef, $ownerJoin, $relationJoin, )); } - private function getOwnerJoin(ModelInspector $ownerModel, ModelInspector $relationModel): string + private function getOwnerJoin(ModelInspector $ownerModel, ModelInspector $relationModel, string $tableAlias): string { $ownerJoin = $this->ownerJoin; $tableReference = $this->isSelfReferencing() ? $this->property->getName() - : $ownerModel->getTableName(); + : $tableAlias; if ($ownerJoin && ! strpos($ownerJoin, '.')) { $ownerJoin = sprintf( diff --git a/packages/database/src/HasManyThrough.php b/packages/database/src/HasManyThrough.php index dbf1609c3..610812b45 100644 --- a/packages/database/src/HasManyThrough.php +++ b/packages/database/src/HasManyThrough.php @@ -17,6 +17,8 @@ #[Attribute(flags: Attribute::TARGET_PROPERTY)] final class HasManyThrough implements Relation { + use HasTableAlias; + public PropertyReflector $property; public string $name { @@ -56,7 +58,7 @@ public function getSelectFields(): ImmutableArray ->map(map: fn ( $field, ) => new FieldStatement( - field: $targetModel->getTableName() . '.' . $field, + field: "{$this->getTableAlias(tableName: $targetModel->getTableName())}.{$field}", ) ->withAlias( alias: sprintf( @@ -152,12 +154,19 @@ private function buildSecondJoin( ModelInspector $intermediateModel, ModelInspector $targetModel, ): string { + $tableAlias = $this->getTableAlias(tableName: $targetModel->getTableName()); + $tableName = $targetModel->getTableName(); + $tableRef = $tableAlias !== $tableName + ? sprintf('%s AS %s', $tableName, $tableAlias) + : $tableName; + return sprintf( 'LEFT JOIN %s ON %s = %s', - $targetModel->getTableName(), + $tableRef, $this->resolveThroughOwnerJoin( targetModel: $targetModel, intermediateModel: $intermediateModel, + tableAlias: $tableAlias, ), $this->resolveThroughRelationJoin(intermediateModel: $intermediateModel), ); @@ -244,6 +253,7 @@ private function resolveRelationJoin(ModelInspector $ownerModel): string private function resolveThroughOwnerJoin( ModelInspector $targetModel, ModelInspector $intermediateModel, + string $tableAlias, ): string { $throughOwnerJoin = $this->throughOwnerJoin; @@ -256,7 +266,7 @@ private function resolveThroughOwnerJoin( ) { return sprintf( '%s.%s', - $targetModel->getTableName(), + $tableAlias, $throughOwnerJoin, ); } @@ -276,7 +286,7 @@ private function resolveThroughOwnerJoin( return sprintf( '%s.%s', - $targetModel->getTableName(), + $tableAlias, str(string: $intermediateModel->getTableName())->singularizeLastWord() . '_' . $primaryKey, ); } diff --git a/packages/database/src/HasOne.php b/packages/database/src/HasOne.php index 9abeb0047..8b1fb9d6e 100644 --- a/packages/database/src/HasOne.php +++ b/packages/database/src/HasOne.php @@ -17,6 +17,8 @@ #[Attribute(Attribute::TARGET_PROPERTY)] final class HasOne implements Relation { + use HasTableAlias; + public PropertyReflector $property; public string $name { @@ -42,7 +44,7 @@ public function getSelectFields(): ImmutableArray $relationModel = inspect($this->property->getType()->asClass()); $tableReference = $this->isSelfReferencing() ? $this->property->getName() - : $relationModel->getTableName(); + : $this->getTableAlias($relationModel->getTableName()); return $relationModel ->getSelectFields() @@ -59,8 +61,13 @@ public function getJoinStatement(): JoinStatement { $ownerModel = inspect($this->property->getType()->asClass()); $relationModel = inspect($this->property->getClass()); + $tableAlias = $this->getTableAlias($ownerModel->getTableName()); - $ownerJoin = $this->getOwnerJoin($ownerModel, $relationModel); + $ownerJoin = $this->getOwnerJoin( + ownerModel: $ownerModel, + relationModel: $relationModel, + tableAlias: $tableAlias, + ); $relationJoin = $this->getRelationJoin($relationModel); if ($this->isSelfReferencing()) { @@ -73,20 +80,25 @@ public function getJoinStatement(): JoinStatement )); } + $tableName = $ownerModel->getTableName(); + $tableRef = $tableAlias !== $tableName + ? sprintf('%s AS %s', $tableName, $tableAlias) + : $tableName; + return new JoinStatement(sprintf( 'LEFT JOIN %s ON %s = %s', - $ownerModel->getTableName(), + $tableRef, $ownerJoin, $relationJoin, )); } - private function getOwnerJoin(ModelInspector $ownerModel, ModelInspector $relationModel): string + private function getOwnerJoin(ModelInspector $ownerModel, ModelInspector $relationModel, string $tableAlias): string { $ownerJoin = $this->ownerJoin; $tableReference = $this->isSelfReferencing() ? $this->property->getName() - : $ownerModel->getTableName(); + : $tableAlias; if ($ownerJoin && ! strpos($ownerJoin, '.')) { $ownerJoin = sprintf( diff --git a/packages/database/src/HasOneThrough.php b/packages/database/src/HasOneThrough.php index b170fd157..5d23f2d23 100644 --- a/packages/database/src/HasOneThrough.php +++ b/packages/database/src/HasOneThrough.php @@ -17,6 +17,8 @@ #[Attribute(flags: Attribute::TARGET_PROPERTY)] final class HasOneThrough implements Relation { + use HasTableAlias; + public PropertyReflector $property; public string $name { @@ -57,7 +59,7 @@ public function getSelectFields(): ImmutableArray map: fn ( $field, ) => new FieldStatement( - field: $targetModel->getTableName() . '.' . $field, + field: "{$this->getTableAlias(tableName: $targetModel->getTableName())}.{$field}", ) ->withAlias( alias: sprintf( @@ -109,12 +111,19 @@ private function buildSecondJoin( ModelInspector $intermediateModel, ModelInspector $targetModel, ): string { + $tableAlias = $this->getTableAlias(tableName: $targetModel->getTableName()); + $tableName = $targetModel->getTableName(); + $tableRef = $tableAlias !== $tableName + ? sprintf('%s AS %s', $tableName, $tableAlias) + : $tableName; + return sprintf( 'LEFT JOIN %s ON %s = %s', - $targetModel->getTableName(), + $tableRef, $this->resolveThroughOwnerJoin( targetModel: $targetModel, intermediateModel: $intermediateModel, + tableAlias: $tableAlias, ), $this->resolveThroughRelationJoin(intermediateModel: $intermediateModel), ); @@ -201,6 +210,7 @@ private function resolveRelationJoin(ModelInspector $ownerModel): string private function resolveThroughOwnerJoin( ModelInspector $targetModel, ModelInspector $intermediateModel, + string $tableAlias, ): string { $throughOwnerJoin = $this->throughOwnerJoin; @@ -213,7 +223,7 @@ private function resolveThroughOwnerJoin( ) { return sprintf( '%s.%s', - $targetModel->getTableName(), + $tableAlias, $throughOwnerJoin, ); } @@ -233,7 +243,7 @@ private function resolveThroughOwnerJoin( return sprintf( '%s.%s', - $targetModel->getTableName(), + $tableAlias, str(string: $intermediateModel->getTableName())->singularizeLastWord() . '_' . $primaryKey, ); } diff --git a/packages/database/src/HasTableAlias.php b/packages/database/src/HasTableAlias.php new file mode 100644 index 000000000..e379f5a72 --- /dev/null +++ b/packages/database/src/HasTableAlias.php @@ -0,0 +1,28 @@ +parent === null || $this->parent === '') { + return $tableName; + } + + return str(string: $this->parent) + ->replace( + search: '.', + replace: '_', + ) + ->append( + '_', + $this->property->getName(), + ) + ->toString(); + } +} diff --git a/tests/Integration/Database/Builder/SelectQueryBuilderTest.php b/tests/Integration/Database/Builder/SelectQueryBuilderTest.php index ad462fe96..acf94a7a8 100644 --- a/tests/Integration/Database/Builder/SelectQueryBuilderTest.php +++ b/tests/Integration/Database/Builder/SelectQueryBuilderTest.php @@ -4,9 +4,12 @@ namespace Tests\Tempest\Integration\Database\Builder; +use Tempest\Database\BelongsToMany; use Tempest\Database\Builder\QueryBuilders\SelectQueryBuilder; use Tempest\Database\Direction; +use Tempest\Database\IsDatabaseModel; use Tempest\Database\Migrations\CreateMigrationsTable; +use Tempest\Database\Table; use Tests\Tempest\Fixtures\Migrations\CreateAuthorTable; use Tests\Tempest\Fixtures\Migrations\CreateBookTable; use Tests\Tempest\Fixtures\Migrations\CreateChapterTable; @@ -491,7 +494,7 @@ public function test_eager_loads_combined_with_manual_loads(): void $query = AWithEager::select()->with('b.c')->compile(); $this->assertSameWithoutBackticks( - 'SELECT a.id AS `a.id`, a.b_id AS `a.b_id`, b.id AS `b.id`, b.c_id AS `b.c_id`, c.id AS `b.c.id`, c.name AS `b.c.name` FROM `a` LEFT JOIN b ON b.id = a.b_id LEFT JOIN c ON c.id = b.c_id', + 'SELECT a.id AS `a.id`, a.b_id AS `a.b_id`, b.id AS `b.id`, b.c_id AS `b.c_id`, b_c.id AS `b.c.id`, b_c.name AS `b.c.name` FROM `a` LEFT JOIN b ON b.id = a.b_id LEFT JOIN c AS b_c ON b_c.id = b.c_id', $query, ); } @@ -735,4 +738,51 @@ public function test_select_with_has_one_through_relation(): void $query->compile(), ); } + + public function test_select_with_duplicate_belongs_to_many_target_table(): void + { + $query = query(model: UserWithRoleAndDirectPermissions::class) + ->select() + ->with('role', 'role.permissions', 'permissions') + ->build(); + + $this->assertSameWithoutBackticks( + 'SELECT users.id AS `users.id`, users.name AS `users.name`, users.role_id AS `users.role_id`, roles.id AS `role.id`, roles.name AS `role.name`, role_permissions.id AS `role.permissions.id`, role_permissions.label AS `role.permissions.label`, permissions.id AS `permissions.id`, permissions.label AS `permissions.label` FROM `users` LEFT JOIN roles ON roles.id = users.role_id LEFT JOIN permissions_roles ON permissions_roles.role_id = roles.id LEFT JOIN permissions AS role_permissions ON role_permissions.id = permissions_roles.permission_id LEFT JOIN permissions_users ON permissions_users.user_id = users.id LEFT JOIN permissions ON permissions.id = permissions_users.permission_id', + $query->compile(), + ); + } +} + +#[Table(name: 'users')] +final class UserWithRoleAndDirectPermissions +{ + use IsDatabaseModel; + + public string $name; + + public ?RoleWithPermissions $role = null; + + /** @var \Tests\Tempest\Integration\Database\Builder\Permission[] */ + #[BelongsToMany(pivot: 'permissions_users')] + public array $permissions = []; +} + +#[Table(name: 'roles')] +final class RoleWithPermissions +{ + use IsDatabaseModel; + + public string $name; + + /** @var \Tests\Tempest\Integration\Database\Builder\Permission[] */ + #[BelongsToMany(pivot: 'permissions_roles')] + public array $permissions = []; +} + +#[Table(name: 'permissions')] +final class Permission +{ + use IsDatabaseModel; + + public string $label; } diff --git a/tests/Integration/Database/CircularEagerLoadingTest.php b/tests/Integration/Database/CircularEagerLoadingTest.php index 2dfaa3e40..c3fe64234 100644 --- a/tests/Integration/Database/CircularEagerLoadingTest.php +++ b/tests/Integration/Database/CircularEagerLoadingTest.php @@ -35,7 +35,7 @@ public function test_circular_with_relations_does_not_cause_infinite_loop(): voi $relations = $userInspector->resolveRelations('profile.user.profile'); $this->assertArrayHasKey('profile', $relations); - $this->assertArrayHasKey('user', $relations); + $this->assertArrayHasKey('profile.user', $relations); $this->assertCount(2, $relations); } diff --git a/tests/Integration/Database/ModelInspector/BelongsToManyTest.php b/tests/Integration/Database/ModelInspector/BelongsToManyTest.php index fb14b4478..ac2d06d4f 100644 --- a/tests/Integration/Database/ModelInspector/BelongsToManyTest.php +++ b/tests/Integration/Database/ModelInspector/BelongsToManyTest.php @@ -54,11 +54,26 @@ public function test_belongs_to_many_with_parent(): void ->setParent(name: 'parent'); $this->assertSame( - expected: 'target.data AS `parent.targets.data`', + expected: 'parent_targets.data AS `parent.targets.data`', actual: $relation->getSelectFields()[1]->compile(DatabaseDialect::SQLITE), ); } + public function test_belongs_to_many_with_parent_join_uses_alias(): void + { + $model = inspect(model: BelongsToManyOwnerModel::class); + $relation = $model + ->getRelation(name: 'targets') + ->setParent(name: 'parent'); + + $this->assertSame( + expected: 'LEFT JOIN owner_target ON owner_target.owner_id = owner.id LEFT JOIN target AS parent_targets ON parent_targets.id = owner_target.target_id', + actual: $relation + ->getJoinStatement() + ->compile(dialect: DatabaseDialect::SQLITE), + ); + } + public function test_belongs_to_many_with_custom_pivot(): void { $model = inspect(model: BelongsToManyCustomOwnerModel::class); diff --git a/tests/Integration/Database/ModelInspector/BelongsToTest.php b/tests/Integration/Database/ModelInspector/BelongsToTest.php index 0cf57fd75..7c2747510 100644 --- a/tests/Integration/Database/ModelInspector/BelongsToTest.php +++ b/tests/Integration/Database/ModelInspector/BelongsToTest.php @@ -85,7 +85,7 @@ public function test_belongs_to_with_parent(): void $relation = $model->getRelation('relation')->setParent('parent'); $this->assertSame( - 'relation.name AS `parent.relation.name`', + 'parent_relation.name AS `parent.relation.name`', $relation->getSelectFields()[1]->compile(DatabaseDialect::SQLITE), ); } diff --git a/tests/Integration/Database/ModelInspector/HasManyTest.php b/tests/Integration/Database/ModelInspector/HasManyTest.php index abcf14d89..574c06d59 100644 --- a/tests/Integration/Database/ModelInspector/HasManyTest.php +++ b/tests/Integration/Database/ModelInspector/HasManyTest.php @@ -80,7 +80,7 @@ public function test_has_many_with_parent(): void $relation = $model->getRelation('owners')->setParent('parent'); $this->assertSame( - 'owner.relation_id AS `parent.owners.relation_id`', + 'parent_owners.relation_id AS `parent.owners.relation_id`', $relation->getSelectFields()[1]->compile(DatabaseDialect::SQLITE), ); } diff --git a/tests/Integration/Database/ModelInspector/HasManyThroughTest.php b/tests/Integration/Database/ModelInspector/HasManyThroughTest.php index 9ec5fa806..ab0ef08d9 100644 --- a/tests/Integration/Database/ModelInspector/HasManyThroughTest.php +++ b/tests/Integration/Database/ModelInspector/HasManyThroughTest.php @@ -59,7 +59,7 @@ public function test_has_many_through_with_parent(): void ->setParent(name: 'parent'); $this->assertSame( - expected: 'target.data AS `parent.targets.data`', + expected: 'parent_targets.data AS `parent.targets.data`', actual: $relation->getSelectFields()[2]->compile(DatabaseDialect::SQLITE), ); } diff --git a/tests/Integration/Database/ModelInspector/HasOneTest.php b/tests/Integration/Database/ModelInspector/HasOneTest.php index 6c91a3c66..5019ed3d3 100644 --- a/tests/Integration/Database/ModelInspector/HasOneTest.php +++ b/tests/Integration/Database/ModelInspector/HasOneTest.php @@ -80,7 +80,7 @@ public function test_has_one_with_parent(): void $relation = $model->getRelation('owner')->setParent('parent'); $this->assertSame( - 'owner.relation_id AS `parent.owner.relation_id`', + 'parent_owner.relation_id AS `parent.owner.relation_id`', $relation->getSelectFields()[1]->compile(DatabaseDialect::SQLITE), ); } diff --git a/tests/Integration/Database/ModelInspector/HasOneThroughTest.php b/tests/Integration/Database/ModelInspector/HasOneThroughTest.php index ac6adad85..a4014cda4 100644 --- a/tests/Integration/Database/ModelInspector/HasOneThroughTest.php +++ b/tests/Integration/Database/ModelInspector/HasOneThroughTest.php @@ -55,7 +55,7 @@ public function test_has_one_through_with_parent(): void ->setParent(name: 'parent'); $this->assertSame( - expected: 'target.data AS `parent.target.data`', + expected: 'parent_target.data AS `parent.target.data`', actual: $relation->getSelectFields()[2]->compile(DatabaseDialect::SQLITE), ); }