diff --git a/src/Illuminate/Database/Eloquent/Collection.php b/src/Illuminate/Database/Eloquent/Collection.php index 5e10cd1cde6a..30e8ef0baa69 100755 --- a/src/Illuminate/Database/Eloquent/Collection.php +++ b/src/Illuminate/Database/Eloquent/Collection.php @@ -62,6 +62,30 @@ public function load($relations) return $this; } + /** + * Load a set of relationships onto the mixed relationship collection. + * + * @param string $relation + * @param array $relations + * @return $this + */ + public function loadMorph($relation, $relations) + { + $this->pluck($relation) + ->groupBy(function ($model) { + return get_class($model); + }) + ->filter(function ($models, $className) use ($relations) { + return Arr::has($relations, $className); + }) + ->each(function ($models, $className) use ($relations) { + $className::with($relations[$className]) + ->eagerLoadRelations($models->all()); + }); + + return $this; + } + /** * Add an item to the collection. * diff --git a/src/Illuminate/Pagination/AbstractPaginator.php b/src/Illuminate/Pagination/AbstractPaginator.php index 78b2e0743305..2cd926637fe2 100644 --- a/src/Illuminate/Pagination/AbstractPaginator.php +++ b/src/Illuminate/Pagination/AbstractPaginator.php @@ -521,6 +521,20 @@ public function setCollection(Collection $collection) return $this; } + /** + * Load a set of relationships onto the mixed relationship collection. + * + * @param string $relation + * @param array $relations + * @return $this + */ + public function loadMorph($relation, $relations) + { + $this->getCollection()->loadMorph($relation, $relations); + + return $this; + } + /** * Determine if the given item exists. * diff --git a/tests/Database/DatabaseEloquentPolymorphicIntegrationTest.php b/tests/Database/DatabaseEloquentPolymorphicIntegrationTest.php index cfc01ef384b2..b26fcb720e4c 100644 --- a/tests/Database/DatabaseEloquentPolymorphicIntegrationTest.php +++ b/tests/Database/DatabaseEloquentPolymorphicIntegrationTest.php @@ -4,7 +4,6 @@ use PHPUnit\Framework\TestCase; use Illuminate\Database\Connection; -use Illuminate\Database\Query\Builder; use Illuminate\Database\Capsule\Manager as DB; use Illuminate\Database\Eloquent\Model as Eloquent; @@ -119,6 +118,26 @@ public function testItLoadsNestedRelationshipsOnDemand() $this->assertEquals(TestUser::first(), $like->likeable->owner); } + public function testItLoadsNestedMorphRelationshipsOnDemand() + { + $this->seedData(); + + TestPost::first()->likes()->create([]); + + $likes = TestLike::with('likeable.owner')->get()->loadMorph('likeable', [ + TestComment::class => ['commentable'], + TestPost::class => 'comments', + ]); + + $this->assertTrue($likes[0]->relationLoaded('likeable')); + $this->assertTrue($likes[0]->likeable->relationLoaded('owner')); + $this->assertTrue($likes[0]->likeable->relationLoaded('commentable')); + + $this->assertTrue($likes[1]->relationLoaded('likeable')); + $this->assertTrue($likes[1]->likeable->relationLoaded('owner')); + $this->assertTrue($likes[1]->likeable->relationLoaded('comments')); + } + /** * Helpers... */ @@ -144,7 +163,7 @@ protected function connection() /** * Get a schema builder instance. * - * @return Schema\Builder + * @return \Illuminate\Database\Schema\Builder */ protected function schema() { @@ -183,6 +202,11 @@ public function owner() { return $this->belongsTo(TestUser::class, 'user_id'); } + + public function likes() + { + return $this->morphMany(TestLike::class, 'likeable'); + } } /** diff --git a/tests/Pagination/PaginatorLoadMorphTest.php b/tests/Pagination/PaginatorLoadMorphTest.php new file mode 100644 index 000000000000..0fdb069202b6 --- /dev/null +++ b/tests/Pagination/PaginatorLoadMorphTest.php @@ -0,0 +1,27 @@ + 'photos', + 'App\\Company' => ['employees', 'calendars'], + ]; + + $items = Mockery::mock(Collection::class); + $items->shouldReceive('loadMorph')->with('parentable', $relations); + + $p = (new class extends AbstractPaginator { + })->setCollection($items); + + $this->assertSame($p, $p->loadMorph('parentable', $relations)); + } +}