From 647abf7b90da9ef074b1787966fca5300e6741ef Mon Sep 17 00:00:00 2001 From: Jeremy Mikola Date: Mon, 17 Jun 2024 20:50:20 -0400 Subject: [PATCH 1/4] PHPORM-175: Use foreign key name for MorphTo relationships Incorporates the proposed solution in mongodb/laravel-mongodb#2783 to not default $ownerKey to the current model's key name when constructing a MorphTo in HybridRelations::morphTo(). That change alone caused RelationsTest::testMorph() to fail, since MorphTo::addConstraints() would attempt to use a null ownerKey value. This required an additional change to fall back to the foreign key name when building the constraint. --- src/Eloquent/HybridRelations.php | 2 +- src/Relations/MorphTo.php | 2 +- tests/Ticket/GH2783Test.php | 74 ++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 tests/Ticket/GH2783Test.php diff --git a/src/Eloquent/HybridRelations.php b/src/Eloquent/HybridRelations.php index 5c058f50f..be20327ee 100644 --- a/src/Eloquent/HybridRelations.php +++ b/src/Eloquent/HybridRelations.php @@ -226,7 +226,7 @@ public function morphTo($name = null, $type = null, $id = null, $ownerKey = null $this->newQuery(), $this, $id, - $ownerKey ?: $this->getKeyName(), + $ownerKey, $type, $name, ); diff --git a/src/Relations/MorphTo.php b/src/Relations/MorphTo.php index 1eff5e53b..692991372 100644 --- a/src/Relations/MorphTo.php +++ b/src/Relations/MorphTo.php @@ -17,7 +17,7 @@ public function addConstraints() // 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->ownerKey ?? $this->getForeignKeyName(), '=', $this->getForeignKeyFrom($this->parent), ); diff --git a/tests/Ticket/GH2783Test.php b/tests/Ticket/GH2783Test.php new file mode 100644 index 000000000..c5b605c52 --- /dev/null +++ b/tests/Ticket/GH2783Test.php @@ -0,0 +1,74 @@ + 'Lorem ipsum']); + $user = GH2783User::create(['username' => 'jsmith']); + + $imageWithPost = GH2783Image::create(['uri' => 'http://example.com/post.png']); + $imageWithPost->imageable()->associate($post)->save(); + + $imageWithUser = GH2783Image::create(['uri' => 'http://example.com/user.png']); + $imageWithUser->imageable()->associate($user)->save(); + + $queriedImageWithPost = GH2783Image::with('imageable')->find($imageWithPost->getKey()); + $this->assertInstanceOf(GH2783Post::class, $queriedImageWithPost->imageable); + $this->assertEquals($post->_id, $queriedImageWithPost->imageable->getKey()); + + $queriedImageWithUser = GH2783Image::with('imageable')->find($imageWithUser->getKey()); + $this->assertInstanceOf(GH2783User::class, $queriedImageWithUser->imageable); + $this->assertEquals($user->username, $queriedImageWithUser->imageable->getKey()); + } +} + +class GH2783Image extends Model +{ + protected $connection = 'mongodb'; + protected $fillable = ['uri']; + + public function imageable(): MorphTo + { + return $this->morphTo(__FUNCTION__, 'imageable_type', 'imageable_id'); + } +} + +class GH2783Post extends Model +{ + protected $connection = 'mongodb'; + protected $fillable = ['text']; + + public function image(): MorphOne + { + return $this->morphOne(GH2783Image::class, 'imageable'); + } +} + +class GH2783User extends Model +{ + protected $connection = 'mongodb'; + protected $fillable = ['username']; + protected $primaryKey = 'username'; + + public function image(): MorphOne + { + return $this->morphOne(GH2783Image::class, 'imageable'); + } +} From 96ef757e3ce541863aec73e891771472488607cd Mon Sep 17 00:00:00 2001 From: Jeremy Mikola Date: Thu, 20 Jun 2024 10:43:24 -0400 Subject: [PATCH 2/4] Add missing use statement --- tests/Ticket/GH2783Test.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Ticket/GH2783Test.php b/tests/Ticket/GH2783Test.php index c5b605c52..4cdd77785 100644 --- a/tests/Ticket/GH2783Test.php +++ b/tests/Ticket/GH2783Test.php @@ -6,6 +6,7 @@ use MongoDB\Laravel\Eloquent\Model; use MongoDB\Laravel\Relations\MorphTo; +use MongoDB\Laravel\Tests\TestCase; use Illuminate\Database\Eloquent\Relations\MorphOne; /** From 468d6d9b1e292b783ee960dbf9ee0cf2440eb5ac Mon Sep 17 00:00:00 2001 From: Jeremy Mikola Date: Thu, 20 Jun 2024 10:43:38 -0400 Subject: [PATCH 3/4] Allow multiple classes in ticket tests --- phpcs.xml.dist | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/phpcs.xml.dist b/phpcs.xml.dist index d7dd1e724..3b7cc671c 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -49,4 +49,8 @@ docs/**/*.php + + + tests/Ticket/*.php + From 6214c2272799831ea374718b3fa1092f620b3521 Mon Sep 17 00:00:00 2001 From: Jeremy Mikola Date: Thu, 20 Jun 2024 11:27:34 -0400 Subject: [PATCH 4/4] Fix use statement order --- tests/Ticket/GH2783Test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Ticket/GH2783Test.php b/tests/Ticket/GH2783Test.php index 4cdd77785..73324ddc0 100644 --- a/tests/Ticket/GH2783Test.php +++ b/tests/Ticket/GH2783Test.php @@ -4,10 +4,10 @@ namespace MongoDB\Laravel\Tests\Ticket; +use Illuminate\Database\Eloquent\Relations\MorphOne; use MongoDB\Laravel\Eloquent\Model; use MongoDB\Laravel\Relations\MorphTo; use MongoDB\Laravel\Tests\TestCase; -use Illuminate\Database\Eloquent\Relations\MorphOne; /** * @see https://github.com/mongodb/laravel-mongodb/issues/2783