Skip to content

Commit

Permalink
[8.x] Fix pivot and morphpivot fresh and refresh methods (#35193)
Browse files Browse the repository at this point in the history
* Fix pivot and morphpivot fresh and refresh methods

* Add tests for refreshing of pivots
  • Loading branch information
axlon authored Nov 13, 2020
1 parent 56f79e2 commit 6a9919d
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 3 deletions.
17 changes: 14 additions & 3 deletions src/Illuminate/Database/Eloquent/Relations/Concerns/AsPivot.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,15 @@ public static function fromRawAttributes(Model $parent, $attributes, $table, $ex
}

/**
* Set the keys for a save update query.
* Set the keys for a select query.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function setKeysForSaveQuery($query)
protected function setKeysForSelectQuery($query)
{
if (isset($this->attributes[$this->getKeyName()])) {
return parent::setKeysForSaveQuery($query);
return parent::setKeysForSelectQuery($query);
}

$query->where($this->foreignKey, $this->getOriginal(
Expand All @@ -103,6 +103,17 @@ protected function setKeysForSaveQuery($query)
));
}

/**
* Set the keys for a save update query.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function setKeysForSaveQuery($query)
{
return $this->setKeysForSelectQuery($query);
}

/**
* Delete the pivot model record from the database.
*
Expand Down
13 changes: 13 additions & 0 deletions src/Illuminate/Database/Eloquent/Relations/MorphPivot.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,19 @@ protected function setKeysForSaveQuery($query)
return parent::setKeysForSaveQuery($query);
}

/**
* Set the keys for a select query.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function setKeysForSelectQuery($query)
{
$query->where($this->morphType, $this->morphClass);

return parent::setKeysForSelectQuery($query);
}

/**
* Delete the pivot model record from the database.
*
Expand Down
71 changes: 71 additions & 0 deletions tests/Database/DatabaseEloquentIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Model as Eloquent;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Database\Eloquent\Relations\MorphPivot;
use Illuminate\Database\Eloquent\Relations\Pivot;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Database\Eloquent\SoftDeletes;
Expand Down Expand Up @@ -126,6 +127,18 @@ protected function createSchema()
$table->timestamps();
$table->softDeletes();
});

$this->schema($connection)->create('tags', function ($table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});

$this->schema($connection)->create('taggables', function ($table) {
$table->integer('tag_id');
$table->morphs('taggable');
$table->string('taxonomy')->nullable();
});
}

$this->schema($connection)->create('non_incrementing_users', function ($table) {
Expand Down Expand Up @@ -1742,6 +1755,53 @@ public function testChildModelsAreIgnored()
$this->assertFalse(Model::isIgnoringTouch());
}

public function testPivotsCanBeRefreshed()
{
EloquentTestFriendLevel::create(['id' => 1, 'level' => 'acquaintance']);
EloquentTestFriendLevel::create(['id' => 2, 'level' => 'friend']);

$user = EloquentTestUser::create(['id' => 1, 'email' => '[email protected]']);
$user->friends()->create(['id' => 2, 'email' => '[email protected]'], ['friend_level_id' => 1]);

$pivot = $user->friends[0]->pivot;

// Simulate a change that happened externally
DB::table('friends')->where('user_id', 1)->where('friend_id', 2)->update([
'friend_level_id' => 2,
]);

$this->assertInstanceOf(Pivot::class, $freshPivot = $pivot->fresh());
$this->assertEquals(2, $freshPivot->friend_level_id);

$this->assertSame($pivot, $pivot->refresh());
$this->assertEquals(2, $pivot->friend_level_id);
}

public function testMorphPivotsCanBeRefreshed()
{
$post = EloquentTestPost::create(['name' => 'MorphToMany Post', 'user_id' => 1]);
$post->tags()->create(['id' => 1, 'name' => 'News']);

$pivot = $post->tags[0]->pivot;

// Simulate a change that happened externally
DB::table('taggables')
->where([
'taggable_type' => EloquentTestPost::class,
'taggable_id' => 1,
'tag_id' => 1,
])
->update([
'taxonomy' => 'primary',
]);

$this->assertInstanceOf(MorphPivot::class, $freshPivot = $pivot->fresh());
$this->assertEquals('primary', $freshPivot->taxonomy);

$this->assertSame($pivot, $pivot->refresh());
$this->assertEquals('primary', $pivot->taxonomy);
}

/**
* Helpers...
*/
Expand Down Expand Up @@ -1908,6 +1968,17 @@ public function parentPost()
{
return $this->belongsTo(self::class, 'parent_id');
}

public function tags()
{
return $this->morphToMany(EloquentTestTag::class, 'taggable', null, null, 'tag_id')->withPivot('taxonomy');
}
}

class EloquentTestTag extends Eloquent
{
protected $table = 'tags';
protected $guarded = [];
}

class EloquentTestFriendLevel extends Eloquent
Expand Down

0 comments on commit 6a9919d

Please sign in to comment.