Skip to content

Commit

Permalink
Merge pull request #5984 from JosephSilber/direct-morphs
Browse files Browse the repository at this point in the history
[4.2] Set morphs directly
  • Loading branch information
taylorotwell committed Oct 8, 2014
2 parents e29253c + 669c535 commit 42b71be
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 13 deletions.
19 changes: 8 additions & 11 deletions src/Illuminate/Database/Eloquent/Relations/MorphOneOrMany.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,32 +101,29 @@ public function save(Model $model)
*/
public function create(array $attributes)
{
$foreign = $this->getForeignAttributesForCreate();
$instance = $this->related->newInstance($attributes);

// When saving a polymorphic relationship, we need to set not only the foreign
// key, but also the foreign key type, which is typically the class name of
// the parent model. This makes the polymorphic item unique in the table.
$attributes = array_merge($attributes, $foreign);

$instance = $this->related->newInstance($attributes);
$this->setForeignAttributesForCreate($instance);

$instance->save();

return $instance;
}

/**
* Get the foreign ID and type for creating a related model.
* Set the foreign ID and type for creating a related model.
*
* @return array
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
protected function getForeignAttributesForCreate()
protected function setForeignAttributesForCreate(Model $model)
{
$foreign = array($this->getPlainForeignKey() => $this->getParentKey());

$foreign[last(explode('.', $this->morphType))] = $this->morphClass;
$model->{$this->getPlainForeignKey()} = $this->getParentKey();

return $foreign;
$model->{last(explode('.', $this->morphType))} = $this->morphClass;
}

/**
Expand Down
6 changes: 4 additions & 2 deletions tests/Database/DatabaseEloquentMorphTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,10 @@ public function testCreateFunctionOnMorph()
{
// Doesn't matter which relation type we use since they share the code...
$relation = $this->getOneRelation();
$created = m::mock('stdClass');
$relation->getRelated()->shouldReceive('newInstance')->once()->with(array('name' => 'taylor', 'morph_id' => 1, 'morph_type' => get_class($relation->getParent())))->andReturn($created);
$created = m::mock('Illuminate\Database\Eloquent\Model');
$created->shouldReceive('setAttribute')->once()->with('morph_id', 1);
$created->shouldReceive('setAttribute')->once()->with('morph_type', get_class($relation->getParent()));
$relation->getRelated()->shouldReceive('newInstance')->once()->with(array('name' => 'taylor'))->andReturn($created);
$created->shouldReceive('save')->once()->andReturn(true);

$this->assertEquals($created, $relation->create(array('name' => 'taylor')));
Expand Down

0 comments on commit 42b71be

Please sign in to comment.