search

Home  >  Q&A  >  body text

How to sort products by price in ascending order

<p>How to sort products by price in ascending order. The price is calculated based on the price taken from the model Products multiplied by the volume taken from the model Pack. This is how to display all product prices on Laravel. </p> <pre class="brush:php;toolbar:false;">ceil( ( $product->packs->count() > 0 ? $product->packs->sortBy('pivot.add_time')->first()->volume : 1 ) * $product->price )</pre> <p>I tried using this code but got an error. </p> <blockquote> <p>Undefined property: IlluminateDatabaseQueryBuilder::$pack</p> </blockquote> <pre class="lang-php prettyprint-override"><code>if ($request->get('sort') == 'sort-price_desc') { $products = Product::orderBy( function ($product) { return ceil( ($product->packs->count() > 0 ? $product->packs->sortBy('pivot.add_time')->first()->volume : 1) * $product->price ); } )->get(); }<span style="font-family:'sans serif, tahoma, verdana, helvetica';"><span style="white-space:nowrap;"> </span></span> </code></pre> <p><br /></p>
P粉781235689P粉781235689492 days ago655

reply all(1)I'll reply

  • P粉928591383

    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.

    reply
    0
  • Cancelreply