Search code examples
laraveleloquenteager-loadinglaravel-5.7eloquent-relationship

How to join 3 tables with Laravel's Eloquent relationships with Eager Loading?


So, an order has a foreign_key offer_id.

And an offer has a foreign_key item_id.

An item may be in multiple offers. But every offer has one item.

An offer may be in multiple orders. But every order has one offer.

When I do this:

$orders = Auth::user()->orders()
            ->with('offer')
            ->get();

I get this:

id: 3,
user_id: 1,
offer_id: 5,
created_at: "2019-02-15 00:40:31",
updated_at: "2019-02-15 00:40:31",
offer: {
    id: 5,
    item_id: 3,
    created_at: "2019-02-15 00:39:40",
    updated_at: "2019-02-15 00:39:40"
}

As you can see, I can get that for this offer the item_id: 3 But I want to get the whole item; all its columns, not just the id.

Normally, you would join these two tables. How to do this with Eloquent?

Here are my eloquent relationships:

Order

public function offer()
{
    return $this->belongsTo(Offer::class);
}

Offer

public function orders()
{
    return $this->hasMany(Order::class);
}

public function item()
{
    return $this->hasOne(Item::class);
}

Item

public function offers()
{
    return $this->belongsToMany(Offer::class);
}

Solution

  • The answers from both @MihirBhende and @swonder pointed in the right way.

    It should indeed be:

    $orders = Auth::user()->orders()
                ->with('venue')
                ->with('offer.item')
                ->get();
    

    or (same thing):

    $orders = Auth::user()->orders()
                ->with(['venue', 'offer.food'])
                ->get();
    

    But the relationship of the Offer and Item models should be reversed:

    Offer

    public function item()
    {
        return $this->belongsTo(Item::class);
    }
    

    Item

    public function offers()
    {
        return $this->hasMany(Offer::class);
    }