From ce3c62659d3f1c37da053d5fdf0ab9f17ee8d9f3 Mon Sep 17 00:00:00 2001 From: Ash Allen Date: Wed, 20 Nov 2024 22:28:23 +0000 Subject: [PATCH 1/2] Added `for` method to Eloquent models. --- src/Illuminate/Database/Eloquent/Model.php | 18 ++++++++ tests/Database/DatabaseEloquentModelTest.php | 48 ++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/src/Illuminate/Database/Eloquent/Model.php b/src/Illuminate/Database/Eloquent/Model.php index 7afa59933416..9eb6936e7374 100644 --- a/src/Illuminate/Database/Eloquent/Model.php +++ b/src/Illuminate/Database/Eloquent/Model.php @@ -577,6 +577,24 @@ public function forceFill(array $attributes) return static::unguarded(fn () => $this->fill($attributes)); } + /** + * Set the foreign key for a relationship to another model. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @param string|null $relationship + * @return $this + */ + public function for($model, $relationship = null) + { + $relationship ??= Str::camel(class_basename($model)); + + $foreignKey = $this->{$relationship}()->getForeignKeyName(); + + $this->forceFill([$foreignKey => $model->getKey()]); + + return $this; + } + /** * Qualify the given column name by the model's table. * diff --git a/tests/Database/DatabaseEloquentModelTest.php b/tests/Database/DatabaseEloquentModelTest.php index e7f249512bbd..091f5cf3197c 100755 --- a/tests/Database/DatabaseEloquentModelTest.php +++ b/tests/Database/DatabaseEloquentModelTest.php @@ -3178,6 +3178,29 @@ public function testCollectedByAttribute() $this->assertInstanceOf(CustomEloquentCollection::class, $collection); } + + public function testForCanSetForeignKeysForRelationships() + { + $post = new Post(); + $post->id = 123; + + $user = new User(); + $user->id = 456; + + $comment = (new Comment()); + $this->addMockConnection($comment); + + // Set some data so we can make sure "for" isn't clearing it. + $comment->content = 'Hello'; + + $comment + ->for($post, 'blogPost') + ->for($user); + + $this->assertSame($comment->content, 'Hello'); + $this->assertSame($comment->the_post_id, 123); + $this->assertSame($comment->user_id, 456); + } } class EloquentTestObserverStub @@ -3946,3 +3969,28 @@ class EloquentModelWithCollectedByAttribute extends Model class CustomEloquentCollection extends Collection { } + +class User extends Model +{ + protected $guarded = []; +} + +class Post extends Model +{ + protected $guarded = []; +} + +class Comment extends Model +{ + protected $guarded = []; + + public function blogPost(): BelongsTo + { + return $this->belongsTo(Post::class, 'the_post_id'); + } + + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } +} From 9b67d74eb5eb09564b762573d785695d107e12d9 Mon Sep 17 00:00:00 2001 From: Ash Allen Date: Wed, 20 Nov 2024 22:53:18 +0000 Subject: [PATCH 2/2] Fixed failing test. --- tests/Database/DatabaseEloquentModelTest.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/Database/DatabaseEloquentModelTest.php b/tests/Database/DatabaseEloquentModelTest.php index 091f5cf3197c..070b40359a51 100755 --- a/tests/Database/DatabaseEloquentModelTest.php +++ b/tests/Database/DatabaseEloquentModelTest.php @@ -3184,7 +3184,7 @@ public function testForCanSetForeignKeysForRelationships() $post = new Post(); $post->id = 123; - $user = new User(); + $user = new DatabaseEloquentModelTestUser(); $user->id = 456; $comment = (new Comment()); @@ -3194,12 +3194,12 @@ public function testForCanSetForeignKeysForRelationships() $comment->content = 'Hello'; $comment - ->for($post, 'blogPost') - ->for($user); + ->for($post) + ->for($user, 'user'); $this->assertSame($comment->content, 'Hello'); - $this->assertSame($comment->the_post_id, 123); - $this->assertSame($comment->user_id, 456); + $this->assertSame($comment->post_id, 123); + $this->assertSame($comment->the_user_id, 456); } } @@ -3970,7 +3970,7 @@ class CustomEloquentCollection extends Collection { } -class User extends Model +class DatabaseEloquentModelTestUser extends Model { protected $guarded = []; } @@ -3984,13 +3984,13 @@ class Comment extends Model { protected $guarded = []; - public function blogPost(): BelongsTo + public function post(): BelongsTo { - return $this->belongsTo(Post::class, 'the_post_id'); + return $this->belongsTo(Post::class); } public function user(): BelongsTo { - return $this->belongsTo(User::class); + return $this->belongsTo(DatabaseEloquentModelTestUser::class, 'the_user_id'); } }