Last Updated: September 09, 2019
·
16.64K
· searsaw

Sorting Nested Laravel Collections

Recently, I was working on a project using the Laravel framework. I wanted to retrieve a customer and then display their transactions on a page. However, I needed the transactions sorted from the most recent to the the earliest (descending order). I was using Eloquent to retrieve the customer and its transactions using the with() function. This returned a collection of transaction objects in the order they were put into the database. There is no definitive order in them. I wanted a way to make sure that they were always returned in descending order just in case something gets messed up and they end up in the database in some weird order. Here is the solution I found.

$customer = User::with('transactions')->find($id);
$customer->transactions = $customer->transactions->sortBy(function($transaction)
        {
            return $transaction->created_at;
        })->reverse();

This will first sort the transactions collection in ascending order. Then it reverses the collection, putting them in descending order. Because sortBy() returns the sorted object, we can chain these methods to make our code more compact and readable. I hope this helps in your future project. Leave comments if it helps!

4 Responses
Add your response

Hi,

The following code should also work (note, that latest() is a shortcut for orderBy('created_at','desc'); see https://github.com/laravel/framework/blob/233196cbef18c45a5775009528ffd8bbcbdf8af5/src/Illuminate/Database/Query/Builder.php#L897 for more information)

$user = User::with(array('transactions' => function($query){ $query->latest(); }))->find($id);</code>

over 1 year ago ·

Awesome thanks Alex! The suggested solution by Ianort doesn't work for me in any combination, I'm using the newest version of laravel 4.1. Yours however works like a charm!

over 1 year ago ·

Thanks for your post ! Would you know why using sortByDesc('created_at') ends in a different answer ? When using your method, it works like a charm for me. However when using the former, after my collection is calling toArray(), I see that some keys have been added.

over 1 year ago ·

Thank you for the post. Worked like a charm.
Does this not exist in the documentation anywhere? Wasn't able to find it.

over 1 year ago ·