P粉9285913832023-08-01 00:26:47
Since the orderBy method of Laravel's Eloquent ORM does not support closure functions as a replacement, the code is incorrect. Instead, it expects the column name and sort direction (ascending or descending) as arguments. In your scenario, you are trying to sort products based on a slightly complex calculated value, which cannot be achieved directly by using orderBy.
One strategy you can adopt is to calculate this field beforehand and store it in the products table, and then sort by this field. Alternatively, you can retrieve the products first and then sort them in memory.
Here's how you might do it in memory:
$products = Product::with('packs')->get(); $products = $products->sort(function ($a, $b) { $aVolume = $a->packs->count() > 0 ? $a->packs->sortBy('pivot.add_time')->first()->volume : 1; $bVolume = $b->packs->count() > 0 ? $b->packs->sortBy('pivot.add_time')->first()->volume : 1; $aPrice = ceil($aVolume * $a->price); $bPrice = ceil($bVolume * $b->price); if ($aPrice == $bPrice) { return 0; } return $aPrice < $bPrice ? -1 : 1; }); if ($request->get('sort') == 'sort-price_desc') { $products = $products->reverse(); }
This code first retrieves all products and their associated packages. The collection is then sorted in memory based on the calculation you provide.