diff --git a/src/Illuminate/Database/Eloquent/Model.php b/src/Illuminate/Database/Eloquent/Model.php index daa6e6d3a30d..6efc6d847025 100644 --- a/src/Illuminate/Database/Eloquent/Model.php +++ b/src/Illuminate/Database/Eloquent/Model.php @@ -520,6 +520,22 @@ public function load($relations) return $this; } + /** + * Eager load relationships on the polymorphic relation of a model. + * + * @param string $relation + * @param array $relations + * @return $this + */ + public function loadMorph($relation, $relations) + { + $className = get_class($this->{$relation}); + + $this->{$relation}->load($relations[$className] ?? []); + + return $this; + } + /** * Eager load relations on the model if they are not already eager loaded. * @@ -550,6 +566,22 @@ public function loadCount($relations) return $this; } + /** + * Eager load relationship counts on the polymorphic relation of a model. + * + * @param string $relation + * @param array $relations + * @return $this + */ + public function loadMorphCount($relation, $relations) + { + $className = get_class($this->{$relation}); + + $this->{$relation}->loadCount($relations[$className] ?? []); + + return $this; + } + /** * Increment a column's value by a given amount. * diff --git a/tests/Integration/Database/EloquentMorphCountLazyEagerLoadingTest.php b/tests/Integration/Database/EloquentMorphCountLazyEagerLoadingTest.php new file mode 100644 index 000000000000..3335421fc942 --- /dev/null +++ b/tests/Integration/Database/EloquentMorphCountLazyEagerLoadingTest.php @@ -0,0 +1,83 @@ +increments('id'); + $table->unsignedInteger('post_id'); + }); + + Schema::create('posts', function (Blueprint $table) { + $table->increments('id'); + }); + + Schema::create('comments', function (Blueprint $table) { + $table->increments('id'); + $table->string('commentable_type'); + $table->integer('commentable_id'); + }); + + $post = Post::create(); + + tap((new Like)->post()->associate($post))->save(); + tap((new Like)->post()->associate($post))->save(); + + (new Comment)->commentable()->associate($post)->save(); + } + + public function testLazyEagerLoading() + { + $comment = Comment::first(); + + $comment->loadMorphCount('commentable', [ + Post::class => ['likes'], + ]); + + $this->assertTrue($comment->relationLoaded('commentable')); + $this->assertEquals(2, $comment->commentable->likes_count); + } +} + +class Comment extends Model +{ + public $timestamps = false; + + public function commentable() + { + return $this->morphTo(); + } +} + +class Post extends Model +{ + public $timestamps = false; + + public function likes() + { + return $this->hasMany(Like::class); + } +} + +class Like extends Model +{ + public $timestamps = false; + + public function post() + { + return $this->belongsTo(Post::class); + } +} diff --git a/tests/Integration/Database/EloquentMorphLazyEagerLoadingTest.php b/tests/Integration/Database/EloquentMorphLazyEagerLoadingTest.php new file mode 100644 index 000000000000..fde0da3f6723 --- /dev/null +++ b/tests/Integration/Database/EloquentMorphLazyEagerLoadingTest.php @@ -0,0 +1,78 @@ +increments('id'); + }); + + Schema::create('posts', function (Blueprint $table) { + $table->increments('post_id'); + $table->unsignedInteger('user_id'); + }); + + Schema::create('comments', function (Blueprint $table) { + $table->increments('id'); + $table->string('commentable_type'); + $table->integer('commentable_id'); + }); + + $user = User::create(); + + $post = tap((new Post)->user()->associate($user))->save(); + + (new Comment)->commentable()->associate($post)->save(); + } + + public function testLazyEagerLoading() + { + $comment = Comment::first(); + + $comment->loadMorph('commentable', [ + Post::class => ['user'], + ]); + + $this->assertTrue($comment->relationLoaded('commentable')); + $this->assertTrue($comment->commentable->relationLoaded('user')); + } +} + +class Comment extends Model +{ + public $timestamps = false; + + public function commentable() + { + return $this->morphTo(); + } +} + +class Post extends Model +{ + public $timestamps = false; + protected $primaryKey = 'post_id'; + + public function user() + { + return $this->belongsTo(User::class); + } +} + +class User extends Model +{ + public $timestamps = false; +}