padawanTony
padawanTony

Reputation: 1359

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);
}

Upvotes: 2

Views: 2448

Answers (3)

padawanTony
padawanTony

Reputation: 1359

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);
}

Upvotes: 0

Mihir Bhende
Mihir Bhende

Reputation: 9055

If by food you mean items in an order, how about :

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

Upvotes: 1

user5283119
user5283119

Reputation:

Laravel Eager Loading

Underneath this you will find nested eager loading:

To eager load nested relationships, you may use "dot" syntax. For example, let's eager load all of the book's authors and all of the author's personal contacts in one Eloquent statement:

$books = App\Book::with('author.contacts')->get();

In your case, we can get nested ones using the dot notation between relationships.

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

Upvotes: 1

Related Questions