简体   繁体   中英

Laravel 5.4: groupBy on for-loop not working as expected

Here is my controller first it's very important to see this controller

public function index( Request $request ) {
        $dateFrom = $request->get( 'dateFrom' );
        $dateTo   = $request->get( 'dateTo' );
        $status   = $request->get( 'orderState' );

        $orders = ( new OrderList() )
            ->whereHas( 'orderDetail', function ( $query ) {
                $query->where( 'supplier_id', Auth::guard( 'supplier' )->user()->id );
            } )
            ->with( 'deliveryList' )
            ->when( $dateFrom, function ( $query ) use ( $dateFrom, $dateTo ) {
                $query->whereBetween( 'created_at', [ $dateFrom, $dateTo ] );
            } )
            ->when( $status, function ( $query ) use ( $status ) {
                $query->where( 'order_state_id', $status )->get();
            } )->get();

        //Order Status
        $orderStates = OrderState::listsTranslations( 'states' )->pluck( 'states', 'id' )->toArray();


        return view( 'supplierComponents.order_list', compact( 'orders', 'orderStates' ) );
    }

and here is also the Models for OrderList and OrderDetail

class OrderList extends Model {
    protected $fillable = [
        ......
        ......
    ];
    public function orderDetail() {
        return $this->hasMany( OrderDetail::class, 'order_id' );
    }

    public function ....
    ....................
    }
}

class OrderDetail extends Model {
    protected $fillable = [
        ......
        ......
    ];

    public function orderId() {
        return $this->belongsTo( OrderList::class, 'order_id' );
    }

    public function productId() {
        return $this->belongsTo( Product::class, 'product_id' );
    }
}

Now I am trying to do groupby in the blade file

@foreach($orders as $order)
     @foreach($order->orderDetail->groupBy('product_id') as $items)
       <tr>
         <td>{!! $items->sum('quantity') !!}</td>
         <td>{!! $items->first()->product_name !!}</td>
         <td>{!! $items->first()->product_id !!}</td>
       </tr>
     @endforeach
@endforeach

Now the results of this array is coming like

-------------------------------------------
product-name   |  quantity  |  product-id | 
-------------------------------------------
Coffey         |     2      |      15     |
Coffey         |     1      |      15     |
Coffey         |     1      |      15     |
tea            |     3      |      22     |
tea            |     2      |      22     |
tea            |     1      |      22     |
-------------------------------------------

which I need it to be something like

-------------------------------------------
product-name   |  quantity  |  product-id | 
-------------------------------------------
Coffey         |     4      |      15     |
tea            |     6      |      22     |
-------------------------------------------

Update

when debug on orders that what I get.

Collection {#708 ▼
  #items: array:14 [▼
    0 => OrderList {#717 ▼
      #fillable: array:4 [▶]
      #connection: "mysql"
      #table: null
      #primaryKey: "id"
      #keyType: "int"
      +incrementing: true
      #with: []
      #withCount: []
      #perPage: 15
      +exists: true
      +wasRecentlyCreated: false
      #attributes: array:6 [▶]
      #original: array:6 [▶]
      #casts: []
      #dates: []
      #dateFormat: null
      #appends: []
      #events: []
      #observables: []
      #relations: array:5 [▼
        "deliveryList" => null
        "orderedUsers" => User {#756 ▶}
        "orderedStates" => OrderState {#763 ▶}
        "orderDetail" => Collection {#782 ▶}
        "address" => CustomerAddressBook {#791 ▶}
      ]
      #touches: []
      +timestamps: true
      #hidden: []
      #visible: []
      #guarded: array:1 [▶]
    }
    1 => OrderList {#718 ▶}
    2 => OrderList {#719 ▶}
    3 => OrderList {#720 ▶}
    4 => OrderList {#721 ▶}

How to achieve this

Try adding groupBy and select in your orderDetail relationship.

$orders = ( new OrderList() )
                   ->whereHas( 'orderDetail', function ( $query ) {
                       $query->where( 'supplier_id', Auth::guard( 'supplier' )->user()->id );
                       $query->groupBy( 'product_id' );
                       $query->select(DB::raw( "SUM(quantity) as quantity_total" ));
            } )

And the quantity_total will be holding the total quantity.

Hope that helps.

As you are returning an object of type OrderList rather than Collection then you will not have access to the groupBy() method.

If you want to apply a groupBy() clause to the underlying query you can do so by accessing the query builder like so:

$order->orderDetail()->groupBy('product_id')

Update

When you have access to a Collection ( Eloquent or Support ), you can group by properties of the objects in your list like so:

$order->groupBy('product_id');

However, in your case I think you are actually wanting to group by properties of related objects. You can do this using the . notation like so:

$order->groupBy('orderDetail.product_id')

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