Laravel hasManyThrough Relationship

hasManyThrough Relationship is one of the most powerful yet underutilized of all the Relationships that Laravel has to offer. Using this Relationship we can drastically improve the readability of the code.

Let us see the following scenario.

We have a User Table. A user can have multiple Posts. Each of those Posts can have multiple Comments. In Laravel Eloquent Terminology, we will have Relationship as User hasMany Posts. Post hasMany Comments. And Relationships will be defined as below.

<?php
class User extends Model
{
    public function posts()
    {
        return $this->hasMany(\App\Post::class);
    }
}


<?php
class Post extends Model
{
    public function comments()
    {
        return $this->hasMany(\App\Comment::class);
    }

    public function user()
    {
        return $this->belongsTo(\App\User::class);
    }
}

<?php
class Comment extends Model
{
    public function post()
    {
        return $this->belongsTo(\App\Post::class);
    }
}

Now lets say we want to fetch all the comments which have been made on all the Posts belonging to a specific User. We will have to first fetch all the Posts belonging to User and then for each Post we will need to fetch all the Comments. This could be accomplished using below code.

        $user = User::find(1);
        $comments = collect();
        $user->posts->each(function( $post) use( $comments) {
            $comments->push( $post->comments);
            
        });
        $comments = $comments->flatten(1);

Even though the above code works, it is certainly not very pretty. Herein our hasManyThrough Relationship comes into effect. This is a perfect example to use hasManyThrough Relationship between User and Comments. We will define it on User Model as below

    public function comments() {
        return $this->hasManyThrough(
            \App\Comment::class,
            \App\Post::class
        );
    }

First Argument is the name of the final Model, which is Comment.
Second Argument is the name of the Intermediate Model, which is Post.
We do not need to define rest of the arguments if you are following the Laravel Conventions.

Now we can simply fetch all the comments of a User using the above relationship.

        $user = User::find(1);
        $comments = $user->comments;

And that is it. Our Code is now far more simpler. And it is definitely easier to understand and manage. So hope you have a good understanding of how effective hasManyThrough Relationship can be.

If you have enjoyed our Tutorial, you can also watch a Video Version of it on our Youtube Channel.
You can also watch our Playlist Laravel Eloquent Relationship Advanced Tutorial which covers all the Relationships that Laravel has to offer including Polymorphic Relationship along with multiple examples and various scenarios.

Leave a Reply

Your email address will not be published. Required fields are marked *