From 2129df75ad3aa037834e71d0d095fb8f564956b7 Mon Sep 17 00:00:00 2001 From: Timothy Winters Date: Mon, 10 May 2021 15:32:26 -0400 Subject: [PATCH] Consistent BelongsToMany#firstOrCreate behaviour --- .../Eloquent/Relations/BelongsToMany.php | 5 ++-- .../Database/EloquentBelongsToManyTest.php | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php b/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php index 13e02fae7f9f..195b000082af 100755 --- a/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php +++ b/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php @@ -609,14 +609,15 @@ public function firstOrNew(array $attributes) * Get the first related record matching the attributes or create it. * * @param array $attributes + * @param array $values * @param array $joining * @param bool $touch * @return \Illuminate\Database\Eloquent\Model */ - public function firstOrCreate(array $attributes, array $joining = [], $touch = true) + public function firstOrCreate(array $attributes, array $values = [], array $joining = [], $touch = true) { if (is_null($instance = $this->related->where($attributes)->first())) { - $instance = $this->create($attributes, $joining, $touch); + $instance = $this->create($attributes + $values, $joining, $touch); } return $instance; diff --git a/tests/Integration/Database/EloquentBelongsToManyTest.php b/tests/Integration/Database/EloquentBelongsToManyTest.php index a7c042cca864..9710953a7c9c 100644 --- a/tests/Integration/Database/EloquentBelongsToManyTest.php +++ b/tests/Integration/Database/EloquentBelongsToManyTest.php @@ -439,6 +439,30 @@ public function testFirstOrCreateMethod() $this->assertNotNull($new->id); } + public function testFirstOrCreateMethodWithValues() + { + $post = Post::create(['title' => Str::random()]); + $tag = Tag::create(['name' => Str::random()]); + $post->tags()->attach(Tag::all()); + + $existing = $post->tags()->firstOrCreate( + ['name' => $tag->name], + ['type' => 'featured'] + ); + + $this->assertEquals($tag->id, $existing->id); + $this->assertNotEquals('foo', $existing->name); + + $new = $post->tags()->firstOrCreate( + ['name' => 'foo'], + ['type' => 'featured'] + ); + + $this->assertSame('foo', $new->name); + $this->assertSame('featured', $new->type); + $this->assertNotNull($new->id); + } + public function testUpdateOrCreateMethod() { $post = Post::create(['title' => Str::random()]);