Laravel - Four levels deep relationship

Viewed 648

I am trying to map a relationship between the User and Order Model within Order Model.

An order has one project. The project has one team and the team has one owner/user

The relationship is four levels deep like following:

order > project > team > user

My database tables are as follows:

App\Order

id, 
project_id

App\Project

id, 
name, 
team_id

App\Team

id
name
user_id

App\User

id
name

My Order Model:

class Order extends Model{
    function customer(){
      // trying to map the relationship here
    }
}

I would like to access the customer like following:

 $order =  Order::find(1);
 echo $order->customer->name;

Could you please tell me how to map the above-mentioned relationship?

2 Answers

You can get it by including joins in your query like:

$data = Order::select('orders.*')
    ->join('projects', 'orders.project_id', '=', 'products.id')
    ->join('teams', 'projects.projects_id', '=', 'teams.id')
    ->join('users', 'teams.teams_id', '=', 'users.id')
    ->get();

For Eloquent you can use this package.

You can define deeper relationships :
OrderbelongsToProjectbelongsToTeambelongsToUser :

class Order extends Model
{
    use \Znck\Eloquent\Traits\BelongsToThrough;

    public function customer()
    {
        return $this->belongsToThrough('App\User', ['App\Team', 'App\Project']);
    }
}

Another way would be to define a belongsTo in your model by adding joins to directly reach users table

class Order extends Model
{

    public function customer()
    {
        return $this->belongsTo(Project::class, 'project_id')
            ->join('team as t', 't.id', '=', 'projects.team_id')
            ->join('users as u', 'u.id', '=', 't.user_id')
            ->select(['u.id as uid','u.name','projects.id']);
    }

}

And then you can directly get the customer information from order object

$order =  Order::find(1);
$order->customer->name;

OR Via eager loding

$orders =  Order::with('customer')->get();
Related