Bun Suwanparsert
Bun Suwanparsert

Reputation: 915

How to order by using appended attribute in Laravel

I created an appends attribute in Laravel Model, from the code below.

    protected $appends = array('total'=>'');

And I set the returned value.

    public function getTotalAttribute(){
           return ProductPart::where('product_id',$this->id)->count();
    }

Then I want to order records from database by using total attribute

I tried to use Product::orderBy('total','desc')->get() but it didn't work.

Does anybody has some suggestions to this?

Upvotes: 16

Views: 25942

Answers (6)

FreddicMatters
FreddicMatters

Reputation: 431

This my example using attributes:

$collectionCenters = Supplier::where('supplier_type','=','persona_juridica')->get();
// Ordenar de forma descendente las cantidades
if ($this->unit == "kg") {
    $collectionCenters = $collectionCenters->sortByDesc(function($cc) {
        return $cc->qty_sold_kg;
    });
}
if ($this->unit == "t") {
    $collectionCenters = $collectionCenters->sortByDesc(function($cc){
        return $cc->qty_sold_tons;
    });
}

Then in my blade I jus call the attribute:

<td>
    @if($unit == "kg")
        {{ $cc->qty_sold_kg }}
    @elseif($unit == "t")
        {{ $cc->qty_sold_tons }}
    @endif
</td>
<td>{{ $cc->details->ruc }}</td>
<td>{{ $cc->details->companyName }}</td>

Upvotes: 0

guizo
guizo

Reputation: 3105

You can use the sortBy method from collections.

$products = Product::all();
$products = $products->sortBy('total');

Upvotes: 0

Peter Pointer
Peter Pointer

Reputation: 4170

As mentioned, the proposed solution using a sortBy() callback does not work with paging.
Here is an alternative to the accepted solution:

orderByRaw()

If the appended attributes can be calculated from the fields in your query you can instead use orderByRaw(), like so:

// For example, booking percentage
$query->orderByRaw('bookings_count / total_count');

Check out a more advanced example here: laravel orderByRaw() on the query builder

Upvotes: 0

eylay
eylay

Reputation: 2168

use sortBy for ASC

$collection->sortBy('field');

use sortByDesc for DESC

$collection->sortByDesc('field');

Upvotes: 2

Philipp
Philipp

Reputation: 197

If working with attributes those are not always available instantly (e.g. for freshly created models).

As expansion on Ayobami Opeyemi's answer you should be able to use Collection's sortBy if you force the attribute to evaluate by calling its function directly:

$products = Product::all();
$products = $products->sortBy(function($product){
    return $product->getTotalAttribute();
});

https://laravel.com/docs/master/collections#method-sortby

Upvotes: 2

Ayobami Opeyemi
Ayobami Opeyemi

Reputation: 752

the orderBy takes an actual database field not an appended one

try this

$products = Product::all();
$products = $products->sortBy(function($product){
    return $product->total;
});

Upvotes: 25

Related Questions