From d7bfc917325b5d5d5a81b821656ad802cea547be Mon Sep 17 00:00:00 2001 From: Duilio Palacios Date: Sat, 12 Nov 2016 11:15:52 +0000 Subject: [PATCH] Improve hasOne->withDefault closure option and add array option as well. --- .../Database/Eloquent/Relations/HasOne.php | 21 ++++++--- tests/Database/DatabaseEloquentHasOneTest.php | 44 +++++++++++++++++-- 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Relations/HasOne.php b/src/Illuminate/Database/Eloquent/Relations/HasOne.php index ca83020e87b2..2b4bd3913b18 100755 --- a/src/Illuminate/Database/Eloquent/Relations/HasOne.php +++ b/src/Illuminate/Database/Eloquent/Relations/HasOne.php @@ -2,7 +2,6 @@ namespace Illuminate\Database\Eloquent\Relations; -use Closure; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Collection; @@ -77,12 +76,22 @@ public function match(array $models, Collection $results, $relation) */ protected function getDefaultFor(Model $model) { + if (! $this->withDefault) { + return; + } + + $instance = $this->related->newInstance()->setAttribute( + $this->getPlainForeignKey(), $model->getAttribute($this->localKey) + ); + if (is_callable($this->withDefault)) { - return call_user_func($this->withDefault); - } elseif ($this->withDefault === true) { - return $this->related->newInstance()->setAttribute( - $this->getPlainForeignKey(), $model->getAttribute($this->localKey) - ); + return call_user_func($this->withDefault, $instance) ?: $instance; } + + if (is_array($this->withDefault)) { + $instance->forceFill($this->withDefault); + } + + return $instance; } } diff --git a/tests/Database/DatabaseEloquentHasOneTest.php b/tests/Database/DatabaseEloquentHasOneTest.php index 9c447c58caf5..099220abb436 100755 --- a/tests/Database/DatabaseEloquentHasOneTest.php +++ b/tests/Database/DatabaseEloquentHasOneTest.php @@ -23,13 +23,51 @@ public function testHasOneWithDefault() $this->builder->shouldReceive('first')->once()->andReturnNull(); - $newModel = m::mock('Illuminate\Database\Eloquent\Model'); + $newModel = new EloquentHasOneModelStub(); - $newModel->shouldReceive('setAttribute')->once()->with('foreign_key', 1)->andReturn($newModel); + $this->related->shouldReceive('newInstance')->once()->andReturn($newModel); + + $this->assertSame($newModel, $relation->getResults()); + + $this->assertSame(1, $newModel->getAttribute('foreign_key')); + } + + public function testHasOneWithDynamicDefault() + { + $relation = $this->getRelation()->withDefault(function ($newModel) { + $newModel->username = 'taylor'; + }); + + $this->builder->shouldReceive('first')->once()->andReturnNull(); + + $newModel = new EloquentHasOneModelStub(); $this->related->shouldReceive('newInstance')->once()->andReturn($newModel); - $this->assertInstanceOf('Illuminate\Database\Eloquent\Model', $relation->getResults()); + $this->assertSame($newModel, $relation->getResults()); + + $this->assertSame('taylor', $newModel->username); + + $this->assertSame(1, $newModel->getAttribute('foreign_key')); + } + + public function testHasOneWithArrayDefault() + { + $attributes = ['username' => 'taylor']; + + $relation = $this->getRelation()->withDefault($attributes); + + $this->builder->shouldReceive('first')->once()->andReturnNull(); + + $newModel = new EloquentHasOneModelStub(); + + $this->related->shouldReceive('newInstance')->once()->andReturn($newModel); + + $this->assertSame($newModel, $relation->getResults()); + + $this->assertSame('taylor', $newModel->username); + + $this->assertSame(1, $newModel->getAttribute('foreign_key')); } public function testSaveMethodSetsForeignKeyOnModel()