diff --git a/src/Illuminate/Database/Eloquent/Relations/Concerns/AsPivot.php b/src/Illuminate/Database/Eloquent/Relations/Concerns/AsPivot.php index 88eb54aebfe1..c23f5b9af9a2 100644 --- a/src/Illuminate/Database/Eloquent/Relations/Concerns/AsPivot.php +++ b/src/Illuminate/Database/Eloquent/Relations/Concerns/AsPivot.php @@ -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( @@ -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. * diff --git a/src/Illuminate/Database/Eloquent/Relations/MorphPivot.php b/src/Illuminate/Database/Eloquent/Relations/MorphPivot.php index b5dba3731a34..98cae8c8838b 100644 --- a/src/Illuminate/Database/Eloquent/Relations/MorphPivot.php +++ b/src/Illuminate/Database/Eloquent/Relations/MorphPivot.php @@ -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. * diff --git a/tests/Database/DatabaseEloquentIntegrationTest.php b/tests/Database/DatabaseEloquentIntegrationTest.php index 3f6bbb1ef17c..c3b33a9d941b 100644 --- a/tests/Database/DatabaseEloquentIntegrationTest.php +++ b/tests/Database/DatabaseEloquentIntegrationTest.php @@ -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; @@ -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) { @@ -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' => 'taylorotwell@gmail.com']); + $user->friends()->create(['id' => 2, 'email' => 'abigailotwell@gmail.com'], ['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... */ @@ -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