diff --git a/src/Eloquent/HybridRelations.php b/src/Eloquent/HybridRelations.php index 9e11605a3..f0824c9fb 100644 --- a/src/Eloquent/HybridRelations.php +++ b/src/Eloquent/HybridRelations.php @@ -221,7 +221,7 @@ public function morphTo($name = null, $type = null, $id = null, $ownerKey = null $this->newQuery(), $this, $id, - $ownerKey, + $ownerKey ?: $this->getKeyName(), $type, $name, ); @@ -236,6 +236,11 @@ public function morphTo($name = null, $type = null, $id = null, $ownerKey = null $ownerKey ??= $instance->getKeyName(); + // Check if it is a relation with an original model. + if (! is_subclass_of($instance, MongoDBModel::class)) { + return parent::morphTo($name, $type, $id, $ownerKey); + } + return new MorphTo( $instance->newQuery(), $this, diff --git a/src/Relations/MorphTo.php b/src/Relations/MorphTo.php index 53b93f8d7..1eff5e53b 100644 --- a/src/Relations/MorphTo.php +++ b/src/Relations/MorphTo.php @@ -16,7 +16,11 @@ public function addConstraints() // For belongs to relationships, which are essentially the inverse of has one // or has many relationships, we need to actually query on the primary key // of the related models matching on the foreign key that's on a parent. - $this->query->where($this->ownerKey, '=', $this->parent->{$this->foreignKey}); + $this->query->where( + $this->ownerKey, + '=', + $this->getForeignKeyFrom($this->parent), + ); } } diff --git a/tests/Models/Photo.php b/tests/Models/Photo.php index dbb92b0ff..74852dc28 100644 --- a/tests/Models/Photo.php +++ b/tests/Models/Photo.php @@ -17,4 +17,9 @@ public function hasImage(): MorphTo { return $this->morphTo(); } + + public function hasImageWithCustomOwnerKey(): MorphTo + { + return $this->morphTo(ownerKey: 'cclient_id'); + } } diff --git a/tests/RelationsTest.php b/tests/RelationsTest.php index 6b2e2539f..a4a1c7a84 100644 --- a/tests/RelationsTest.php +++ b/tests/RelationsTest.php @@ -470,6 +470,25 @@ public function testMorph(): void $relations = $photos[1]->getRelations(); $this->assertArrayHasKey('hasImage', $relations); $this->assertInstanceOf(Client::class, $photos[1]->hasImage); + + // inverse + $photo = Photo::query()->create(['url' => 'https://graph.facebook.com/hans.thomas/picture']); + $client = Client::create(['name' => 'Hans Thomas']); + $photo->hasImage()->associate($client)->save(); + + $this->assertCount(1, $photo->hasImage()->get()); + $this->assertInstanceOf(Client::class, $photo->hasImage); + $this->assertEquals($client->_id, $photo->hasImage->_id); + + // inverse with custom ownerKey + $photo = Photo::query()->create(['url' => 'https://graph.facebook.com/young.gerald/picture']); + $client = Client::create(['cclient_id' => (string) (new ObjectId()), 'name' => 'Young Gerald']); + $photo->hasImageWithCustomOwnerKey()->associate($client)->save(); + + $this->assertCount(1, $photo->hasImageWithCustomOwnerKey()->get()); + $this->assertInstanceOf(Client::class, $photo->hasImageWithCustomOwnerKey); + $this->assertEquals($client->cclient_id, $photo->has_image_with_custom_owner_key_id); + $this->assertEquals($client->_id, $photo->hasImageWithCustomOwnerKey->_id); } public function testHasManyHas(): void