简体   繁体   中英

Group Laravel Eloquent pivot values by id

I have a relational database whose models look like this:
Restaurant:

class Restaurant extends Authenticatable
{
    public function dishes()
    {
        // return $this->hasMany(Dish::class);
        return $this->belongsToMany('App\Models\Dish');
    }
}

Dish:

class Dish extends Model
{
    public function orders()
    {
        return $this->belongsToMany('App\Models\Order')->withPivot('quantity');
    }

    public function restaurant()
    {
        return $this->belongsToMany('App\Models\Restaurant');
    }
}

Order

class Order extends Model
{
    public function dishes()
    {
        return $this->belongsToMany('App\Models\Dish');
    }
}

I'm retrieving all orders belonging to the restaurant by id like so:

public function index($id)
    {
        $user_id = $id;
        $dishes = Dish::where('restaurant_id', $user_id)->get();

        foreach ($dishes as $dish => $value) {
            $orders = $value->orders;
            foreach ($orders as $order => $value) {
                $response[] = $value;
            }
        }
        return response()->json($response);
    }

This works, but I would like to group these results by order_id in some way, so that I get returned something similar to this:

 {
        "id": 28,
        "status": 1,
        "address": "Fish Street",
        "user_name": "Artyom",
        "user_surname": "Pyotrovich",
        "phone": "351 351 643 52",
        "email": "artyom@restaurant.com",
        "total": 35.8,
        "created_at": "2021-11-17T10:44:58.000000Z",
        "updated_at": "2021-11-17T10:44:58.000000Z",
        "dishes": [{
            "dish_id": 22,
            "quantity": 3
                   }, 
                   {
            "dish_id": 23,
            "quantity": 1
                  }]
    }

Is this possible by simply changing the Eloquent query or do I need to perform several operations on the result of my current query? Also interested in what is actually the best practice in these cases. Thanks in advance

You can use the ::with() method to get all the desired relations, this is much cleaner then a foreach rewrite.

Example:

$orders = Order::with('dishes')
    ->whereHas('dishes', function(Builder $dishes) use ($user_id) {
        $dishes->where('restaurant_id', $user_id);
    })->get();

return response()->json( $order );

Small note:

Separate the user id from the restaurant id, what if the user has multiple restaurants?

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