Skip to content

Commit 8ca5bbf

Browse files
laylatichygitbutler-client
authored andcommitted
fix(database): derive BelongsTo FK column from property name instead of table name
When two properties reference the same model (e.g. User $author and ?User $reviewer), getOwnerFieldName() derived both FK columns from the related table name (user_id), causing the second to overwrite the first in INSERT data arrays. Use property name instead: author -> author_id, reviewer -> reviewer_id. For the common case where property name matches the singularized table name (Author $author), the result is identical.
1 parent 07341d6 commit 8ca5bbf

4 files changed

Lines changed: 6 additions & 6 deletions

File tree

packages/database/src/BelongsTo.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public function getOwnerFieldName(): string
5757
throw ModelDidNotHavePrimaryColumn::neededForRelation($relationModel->getName(), 'BelongsTo');
5858
}
5959

60-
return str($relationModel->getTableName())->singularizeLastWord() . '_' . $primaryKey;
60+
return str($this->property->getName())->snake() . '_' . $primaryKey;
6161
}
6262

6363
public function getSelectFields(): ImmutableArray

tests/Integration/Database/ModelInspector/BelongsToTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function test_belongs_to_with_relation_join_field(): void
3535
$this->assertInstanceOf(BelongsTo::class, $relation);
3636

3737
$this->assertEquals(
38-
'LEFT JOIN relation ON relation.overwritten_id = owner.relation_id',
38+
'LEFT JOIN relation ON relation.overwritten_id = owner.relation_join_field_id',
3939
$relation->getJoinStatement()->compile(DatabaseDialect::SQLITE),
4040
);
4141
}
@@ -48,7 +48,7 @@ public function test_belongs_to_with_relation_join_field_and_table(): void
4848
$this->assertInstanceOf(BelongsTo::class, $relation);
4949

5050
$this->assertEquals(
51-
'LEFT JOIN relation ON overwritten.overwritten_id = owner.relation_id',
51+
'LEFT JOIN relation ON overwritten.overwritten_id = owner.relation_join_field_and_table_id',
5252
$relation->getJoinStatement()->compile(DatabaseDialect::SQLITE),
5353
);
5454
}

tests/Integration/Database/ModelInspector/LatinPluralRelationTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public function belongs_to_with_latin_plural_property_name(): void
2727
);
2828

2929
$this->assertSame(
30-
expected: 'LEFT JOIN metadata ON metadata.id = products.metadata_id',
30+
expected: 'LEFT JOIN metadata ON metadata.id = products.product_metadata_id',
3131
actual: $relation
3232
->getJoinStatement()
3333
->compile(dialect: DatabaseDialect::SQLITE),
@@ -65,7 +65,7 @@ public function latin_plural_belongs_to_uses_fk_in_select_fields(): void
6565
$fields = $model->getSelectFields()->toArray();
6666

6767
$this->assertContains(
68-
needle: 'metadata_id',
68+
needle: 'product_metadata_id',
6969
haystack: $fields,
7070
);
7171
$this->assertNotContains(

tests/Integration/Database/ModelInspector/SnakeCaseRelationTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public function test_belongs_to_with_snake_case_property(): void
2424
actual: $relation,
2525
);
2626
$this->assertSame(
27-
expected: 'LEFT JOIN author ON author.id = book.author_id',
27+
expected: 'LEFT JOIN author ON author.id = book.main_author_id',
2828
actual: $relation
2929
->getJoinStatement()
3030
->compile(dialect: DatabaseDialect::SQLITE),

0 commit comments

Comments
 (0)