Skip to content

Commit

Permalink
[5.4] Return a Database Collection from HasOneOrMany::createMany (#15944
Browse files Browse the repository at this point in the history
)

* Return an Illuminate\Database\Eloquent\Collection from Illuminate\Database\Eloquent\Relation\HasOneOrMany::createMany

See #15943

* Dry out some tests that expect new or created models with specific attributes

See #15943

* Add a silly trailing comma to satisfy the style gods.

See #15943

* Update the DocBlock comments

See #15943
  • Loading branch information
colindecarlo authored and taylorotwell committed Oct 17, 2016
1 parent e36b7d1 commit 48820f4
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 15 deletions.
8 changes: 4 additions & 4 deletions src/Illuminate/Database/Eloquent/Relations/HasOneOrMany.php
Original file line number Diff line number Diff line change
Expand Up @@ -329,17 +329,17 @@ public function create(array $attributes)
}

/**
* Create an array of new instances of the related model.
* Create a Collection of new instances of the related model.
*
* @param array $records
* @return array
* @return \Illuminate\Database\Eloquent\Collection
*/
public function createMany(array $records)
{
$instances = [];
$instances = $this->related->newCollection();

foreach ($records as $record) {
$instances[] = $this->create($record);
$instances->push($this->create($record));
}

return $instances;
Expand Down
52 changes: 41 additions & 11 deletions tests/Database/DatabaseEloquentHasManyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ public function tearDown()
public function testCreateMethodProperlyCreatesNewModel()
{
$relation = $this->getRelation();
$created = $this->getMockBuilder('Illuminate\Database\Eloquent\Model')->setMethods(['save', 'getKey', 'setAttribute'])->getMock();
$created->expects($this->once())->method('save')->will($this->returnValue(true));
$relation->getRelated()->shouldReceive('newInstance')->once()->with(['name' => 'taylor'])->andReturn($created);
$created->expects($this->once())->method('setAttribute')->with('foreign_key', 1);
$created = $this->expectCreatedModel($relation, ['name' => 'taylor']);

$this->assertEquals($created, $relation->create(['name' => 'taylor']));
}
Expand Down Expand Up @@ -56,10 +53,9 @@ public function testFirstOrNewMethodReturnsNewModelWithForeignKeySet()
$relation = $this->getRelation();
$relation->getQuery()->shouldReceive('where')->once()->with(['foo'])->andReturn($relation->getQuery());
$relation->getQuery()->shouldReceive('first')->once()->with()->andReturn(null);
$relation->getRelated()->shouldReceive('newInstance')->once()->with(['foo'])->andReturn($model = m::mock('StdClass'));
$model->shouldReceive('setAttribute')->once()->with('foreign_key', 1);
$model = $this->expectNewModel($relation, ['foo']);

$this->assertInstanceOf(StdClass::class, $relation->firstOrNew(['foo']));
$this->assertEquals($model, $relation->firstOrNew(['foo']));
}

public function testFirstOrCreateMethodFindsFirstModel()
Expand All @@ -79,11 +75,9 @@ public function testFirstOrCreateMethodCreatesNewModelWithForeignKeySet()
$relation = $this->getRelation();
$relation->getQuery()->shouldReceive('where')->once()->with(['foo'])->andReturn($relation->getQuery());
$relation->getQuery()->shouldReceive('first')->once()->with()->andReturn(null);
$relation->getRelated()->shouldReceive('newInstance')->once()->with(['foo'])->andReturn($model = m::mock('StdClass'));
$model->shouldReceive('save')->once()->andReturn(true);
$model->shouldReceive('setAttribute')->once()->with('foreign_key', 1);
$model = $this->expectCreatedModel($relation, ['foo']);

$this->assertInstanceOf(StdClass::class, $relation->firstOrCreate(['foo']));
$this->assertEquals($model, $relation->firstOrCreate(['foo']));
}

public function testUpdateOrCreateMethodFindsFirstModelAndUpdates()
Expand Down Expand Up @@ -177,6 +171,25 @@ public function testModelsAreProperlyMatchedToParents()
$this->assertEquals(0, count($models[2]->foo));
}

public function testCreateManyCreatesARelatedModelForEachRecord()
{
$records = [
'taylor' => ['name' => 'taylor'],
'colin' => ['name' => 'colin'],
];

$relation = $this->getRelation();
$relation->getRelated()->shouldReceive('newCollection')->once()->andReturn(new Collection);

$taylor = $this->expectCreatedModel($relation, ['name' => 'taylor']);
$colin = $this->expectCreatedModel($relation, ['name' => 'colin']);

$instances = $relation->createMany($records);
$this->assertInstanceOf(Collection::class, $instances);
$this->assertEquals($taylor, $instances[0]);
$this->assertEquals($colin, $instances[1]);
}

protected function getRelation()
{
$builder = m::mock('Illuminate\Database\Eloquent\Builder');
Expand All @@ -191,6 +204,23 @@ protected function getRelation()

return new HasMany($builder, $parent, 'table.foreign_key', 'id');
}

protected function expectNewModel($relation, $attributes = null)
{
$model = $this->getMockBuilder('Illuminate\Database\Eloquent\Model')->setMethods(['setAttribute', 'save'])->getMock();
$relation->getRelated()->shouldReceive('newInstance')->with($attributes)->andReturn($model);
$model->expects($this->once())->method('setAttribute')->with('foreign_key', 1);

return $model;
}

protected function expectCreatedModel($relation, $attributes)
{
$model = $this->expectNewModel($relation, $attributes);
$model->expects($this->once())->method('save');

return $model;
}
}

class EloquentHasManyModelStub extends Illuminate\Database\Eloquent\Model
Expand Down

0 comments on commit 48820f4

Please sign in to comment.