简体   繁体   中英

Laravel Eloquent: hasManyThrough Many to Many relationship

I have the following classes (simplified here) in my Laravel 5.7 model:

VEHICLE.PHP

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Vehicle extends Model
{

    public function journeys()
    {
        return $this->hasMany('App\Journey');
    }

}

JOURNEY PHP

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Journey extends Model
{

    public function vehicle()
    {
       return $this->belongsTo('App\Vehicle');
    }

    public function users()
    {
        return $this->belongsToMany('App\User');
    }
}

USER.PHP

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{  

    public function journeys()
    {
        return $this->belongsToMany('App\Journey');
    }
}

I have an intermediate table (journey_user) between users and journeys (see schema attached).

在此处输入图片说明

I can easily get all journeys made by a particular user. But how can I get all vehicles used by a particular user? The standard hasManyThrough method does not appear to work because of the Many to Many relationship between users and journeys.

Thanks for your help!

I haven't tested this out. However, it should be possible to get all vehicles by looping through all the user 's journeys , creating an array of vehicles and return this as a collection .

This can be added to your User.php model controller:

/**
 * Get all vehicles which user has used
 *
 */
public function vehicles()
{
    $vehicles = [];

    $this->journeys()
        ->each(function ($journey, $key) use (&$vehicles) {
            $vehicles[] = $journey->vehicle;
        });

    return collect($vehicles);
}

Here, we create an empty array. Then we loop through all the journeys of the users (passing the $vehicles array as a reference to update it).

We use the each() collection method to loop through each journey . We create a new entry to the $vehicles array, adding the vehicle .

Finally, we return all vehicles as a collection.

We can use this in our application like so:

User::find($id)->vehicles();

Note : You could return this as an accessor attribute by changing the function name to setVehiclesAttribute() . This will allow you to access the vehicle field like User::find($id)->vehicle .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM