Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

bmcn99's avatar

Having trouble figuring out how to get relationship through eloquent requiring two joins

I have three relevant tables, users, meals, and orders. Users are both customers and restaurants. Users table is pretty standard, meals table has some info about the meal, and a user_id field for the restaurant that it belongs to. Orders table has a user_id for the customer who placed the order, and the meal_id for the meal.

What I want is to get the restaurant(user) from the Order model. I know how to do this in regular SQL:

select * from users
inner join meals on meals.user_id = users.id
inner join orders on orders.meal_id = meals.id
where orders.id = 14

It seems like I would use the hasOneThrough method but I cannot link more than the two tables, so the initial, plus one of the joins is all I get. I don't know how to include the second.

What eloquent tools would I use to get this information?

0 likes
5 replies
Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

It does indeed sound like a hasOneThrough

One the order model

public function owner()
    {
        return $this->hasOneThrough(
            \App\User::class,
            \App\Meal::class,
       );
    }

And user model

 public function order()
    {
        return $this->hasOneThrough(\App\Order::class, \App\Meal::class);
    }
```
And usage 
```
$owner = App\User::whereHas('order', function (Builder $query) {
    $query->where('id', 14);
})->first();
bmcn99's avatar

Thank you! I swapped the placement in the user model to read

return $this->hasOneThrough(\App\Order::class, \App\Meal::class);

In case anyone arrives at this topic looking for help.

While we're on the topic.. I don't think the project I'm working on currently will need more than two joins, but the last one I worked on was heavy on the database side and regularly needed 4-6 joins. Once I get into that territory again should I be switching back to plain SQL queries or expanding this way of doing it somehow?

Sinnbeck's avatar

Try comparing when doing queries. I do a good mix of what is most performant. If I just need some raw data, I use joins etc. Laravel works great for this as well

Sinnbeck's avatar

Oh and oops. Swapped them by mistake. Updated the answer

bmcn99's avatar

An addendum for anyone landing here (Or possibly myself in the future): I wanted to also preserve the relationship when getting the restaurant, not just the collection instance and found something that works, and seems clean enough.

Usage:

$restaurant = $order->restaurant;//gets the restaurant, and so allows $order->restaurant->name and such

Order Model

public function restaurant(){
        return $this->meals->user();
    }
public function meals(){
        return $this->belongsTo(Meal::class, 'meal_id');
    }

Meals Model

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

So in the end it's just chaining belongsTo calls, but it works!

Please or to participate in this conversation.