Skip to main content
Category:

The "has-one-through" relationship links models through a single intermediate relation.

For example, in a vehicle repair shop application, each Mechanic may have one Car, and each Car may have one Owner. While the Mechanic and the Owner have no direct connection, the Mechanic can access the Owner through the Car itself. Let's look at the tables necessary to define this relationship:

mechanics
    id - integer
    name - string

cars
    id - integer
    model - string
    mechanic_id - integer

owners
    id - integer
    name - string
    car_id - integer

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

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Mechanic extends Model
{
    /**
     * Get the car's owner.
     */
    public function carOwner()
    {
        return $this->hasOneThrough('App\Models\Owner', 'App\Models\Car');
    }
}

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

Typical Eloquent foreign key conventions will be used when performing the relationship's queries. If you would like to customize the keys of the relationship, you may pass them as the third and fourth arguments to the hasOneThrough method. The third argument is the name of the foreign key on the intermediate model. The fourth argument is the name of the foreign key on the final model. The fifth argument is the local key, while the sixth argument is the local key of the intermediate model:

class Mechanic extends Model
{
    /**
     * Get the car's owner.
     */
    public function carOwner()
    {
        return $this->hasOneThrough(
            'App\Models\Owner',
            'App\Models\Car',
            'mechanic_id', // Foreign key on cars table...
            'car_id', // Foreign key on owners table...
            'id', // Local key on mechanics table...
            'id' // Local key on cars table...
        );
    }
}

 

Example How to use:

        $mechanic  = Mechanic::find(1);

        $carOwner = $mechanic ->carOwner;

 

Example 2:

 

Consider we have User Model, Reviewer Model and Activity Model with structure :

users
    id - integer
    reviewer_id - integer

reviewers
    id - integer

activities
    id - integer
    user_id - integer

Each reviewer has one user, and each user is associated with one user activity record. If we want to get activity from reviewer, there is no reviewer_id column in activities table, in such case we can use hasOneThrough relation. Let's define the relationship now :

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Reviewer extends Model
{
    /**
     * Get the reviewer's activity.
     */
    public function activity()
    {
        return $this->hasOneThrough('App\Activity', 'App\User');
    }
}

To understand more, lets use Laravel conventional terms on the models. In this case the Activity is the final model we would need to relate, while User is the intermediate model.

As all other relationships in Laravel, we can also explicitely specify the foreign keys while definining hasOneThrough relation, Let's do that for this example :

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Reviewer extends Model
{
    /**
     * Get the reviewer's activity.
     */
    public function activity()
    {
        return $this->hasOneThrough(
            'App\Activity',
            'App\User',
            'reviewer_id', // Foreign key on users table...
            'user_id', // Foreign key on activities table...
            'id', // Local key on reviewers table...
            'id' // Local key on users table...
        );
    }
}

Now you can easily do :

$reviewer = Reviewer::first();
$activity = $reviewer->activity;

 

Riadh Rahmi

Senior Web Developer PHP/Drupal & Laravel

I am a senior web developer, I have experience in planning and developing large scale dynamic web solutions especially in Drupal & Laravel.

Web Posts

Search

Page Facebook