In Laravel, the "has-many-through" relationship provides a convenient way to access distant relations via an intermediate eloquent relation.  For example, let's assume there is a projects environments and deployments table and we want to access the project to deployments. In this case, the has many through relationships is there and we can use this code in laravel 6, laravel 7, laravel 8 and laravel 9.

Eloquent relationships are defined as methods in your Eloquent model classes. We can use the hasManyThrough() method to define "has-many-through" relationships and the first argument passed to the name of the final model we wish to access, while the second argument is the name of the intermediate model.

laravel-hasmanythrough-relationship

See the table structure of the "has-many-through"

Table Structure of hasManyThrough

projects
    id - integer
    name - string
 
environments
    id - integer
    project_id - integer
    name - string
 
deployments
    id - integer
    environment_id - integer
    commit_hash - string

 

In this example, we will see how we can define the has-many-through relationship in laravel and how we can fetch data. So let's see has many through laravel example.

Defining hasManyThrough Relationship

Now that we have the table structure for the relationship, let's define the relationship on the Project model:

app/Models/Project.php

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class Project extends Model
{
    /**
     * Get all of the deployments for the project.
     */
    public function deployments()
    {
        return $this->hasManyThrough(Deployment::class, Environment::class);
    }
}

 

Remember: The first argument passed to the hasManyThrough method is the name of the final model we wish to access, while the second argument is the name of the intermediate model.

 

Read also: Laravel 9 Many To Many | BelongsToMany Eloquent Relationship Tutorial

 

Look at that, the above model like the Deployment model's table does not contain a project_id column, the hasManyThrough relation provides access to a project's deployments via $project->deployments. To retrieve these models, Eloquent expects the project_id column on the Environment table.

Key Conventions of hasManyThrough

Like other relationships in Laravel, typical eloquent foreign key conventions will be used when performing the "has-many-through" relationship queries. If you would like to customize the keys of the relationship, you may pass them as the third and fourth arguments to the hasManyThrough method like.

app/Models/Project.php

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class Project extends Model
{
    /**
     * Get all of the deployments for the project.
     */
    public function deployments()
    {
        return $this->hasManyThrough(
            Deployment::class,
            Environment::class,
            'project_id', // Foreign key on the environments table...
            'environment_id', // Foreign key on the deployments table...
            'id', // Local key on the projects table...
            'id' // Local key on the environments table...
        );
    }
}

 

Read also: Laravel One To One/HasOne Eloquent Relationship Tutorial

 

Conclusion

Now we know laravel 9 has-many-through relationships and how it works. Hope this Laravel 9 has-many-through relationship tutorials will help you.