Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

skoobi's avatar
Level 13

Elequent GroupBy Date and order by Asc inside the date group

Sorry, the thread I opened last week, I marked as answered, and can't un mark it. https://laracasts.com/discuss/channels/laravel/ordering-by-date-and-title

what is happening is that I call "latest()" which I then can group the newest images by date and have the latest ones show at the top. But, what I want to happen once they have been grouped is to order the images in "asc" order so that the images are in the correct order. If I order them by created_at then the documents are displayed backwards which isn't what I want.

After some testing over the past few days it turns out it hasn't worked.

Im not sure why but, while testing I added numbers to the image to make sure they were uploaded in order. It then saved the path and order in the database. From this I can call the path and retrieve the images from s3 storage and as I have the "order_by" column in the database I can use this to order it correctly.

My controller works to get the collection in the date order that I want. But as soon as I add "OrderBy('order', 'asc')" the date ordering is good, but the image order is completely off and random.

My Controller::

    public function show(User $user)
    {
        $collection = CustomerScan::where('user_id', $user->id)
        ->latest()
        ->get()
        ->groupBy(function ($item) {
            return $item->created_at->format('Y-m-d');
        });

        return view('admin.customers-profile.sections.scan-viewer.show')->with([
            'collection' => $collection,
            'user' => $user
        ]);
    }

My View

@foreach ($collection as $date => $scans)

	<div style="margin-top: 50px;">
		
		@if(Carbon\Carbon::today()->toDateString() == $date)
			<strong>TODAY</strong>
		@elseif(Carbon\Carbon::today()->subDay()->toDateString() == $date)
			<strong>YESTERDAY</strong>
		@else
			<strong>{{ Carbon\Carbon::parse($date)->format('jS F Y') }}</strong>
		@endif
		
		<small style="float: right">
			{{ $scans->count() }} {{ Illuminate\Support\Str::plural('Scan',$scans->count()) }}
		</small>

	</div>

	<hr style="border-top: 1px #ccc solid;">

	<div class="row midsection">

		{{-- @foreach($scans->chunk(3) as $chunk) --}}

			@foreach($scans as $scan)
				{{-- My template layout -- }}
			@endforeach

		{{-- @endforeach --}}

	</div>

@endforeach

Any ideas.?

Many thanks

0 likes
10 replies
NickCourage's avatar

You said "If I order them by created_at then the documents are displayed backwards" - what happens if you don't order them by created_at?

skoobi's avatar
Level 13

Hi @nickcourage.

Sorry the created_at or latest() works fine as its grouping by date 'desc' so the latest items are on the top, its the items inside that group that are backwards.

How it is now:

Today

img 5 img 4 img 3 img 2 img 1

Yesterday

img 3 img 2 img 1

How I want it to look:

Today

img 1 img 2 img 3 img 4 img 5

Yesterday

img 1 img 2 img 3

If that makes sense... :)

MichalOravec's avatar

@skoobi Not tested but try it like this

$collection = CustomerScan::where('user_id', $user->id)->latest()->get()->groupBy(function ($item) {
    return $item->created_at->format('Y-m-d');
})->each->sortBy(function ($scan) {
    return $scan->order;
});
skoobi's avatar
Level 13

Hi @michaloravec. Strangely the scans are still going the wrong way. The date order is correct.

So its still doing

Today (26-05-2020)

img5, img4, img3, img2, img1

Yesterday(25-05-2020)

img3,img2,img1

etc...

Am I missing something, or doing something wrong?

MichalOravec's avatar

@skoobi Try use sortByDesc I don't know your logic in order

$collection = CustomerScan::where('user_id', $user->id)->latest()->get()->groupBy(function ($item) {
    return $item->created_at->format('Y-m-d');
})->each->sortByDesc(function ($scan) {
    return $scan->order;
});
mkshingrakhiya's avatar

Hey @skoobi, Could you please try...

$collection = CustomerScan::where('user_id', $user->id)
    ->orderBy('order_field', 'order_direction')
    ->get()
    ->groupBy(function ($item) {
        return $item->created_at->format('Y-m-d');
    });
skoobi's avatar
Level 13

Hi @mkshingrakhiya. The issue is that doing it that way will order it by the latest scans first which is what I want but then the scan images that are grouped are ordered by latest which is not what id like. Its a bit of a pain as I want it grouped by date so I can display the scans and then order the scans inside the group so that they are ascending. Otherwise the images don't make sense and are backwards.

Hi @michaloravec. Still the same im afraid.

Cheers

skoobi's avatar
Level 13

Not quite sure what im doing wrong to be honest.

The table looks like this (path names aren't img1 and duplicating but just for clarity and easier to see the layout)

id.  |  user_id    | path                    | name.     | order        | created_at  | 
-----------------------------------------------------------------------------------
1   |  23          | \storage\img1.jpg.      | img 1     |  1            | 2020-05-25 |
2   |  23          | \storage\img2.jpg.      | img 2     |  2            | 2020-05-25 | 
3   |  23          | \storage\img3.jpg.      | img 3     |  3            | 2020-05-25 | 
4   |  23          | \storage\img1.jpg.      | img 1     |  1            | 2020-05-26 | 
5   |  23          | \storage\img2.jpg.      | img 2     |  2            | 2020-05-26 | 
6   |  23          | \storage\img3.jpg.      | img 3     |  3            | 2020-05-26 | 
-----------------------------------------------------------------------------------

mkshingrakhiya's avatar

I'm confused. Do scan images have a separate table or it is a single table and you're trying to first group the records and then sort records in each group by order field?

skoobi's avatar
Level 13

The scans are in a table of its own where it stores the path to the image and the order I want it to be in. I then have a blade template that shows all the images on 1 page. The order of the images are important as I need the Latest group on the top so this is where grouping by date is important but within that group (the images) I want to order them in ascending so they become 1,2,3 etc rather than newest first which would be 3,2,1..

So in the table layout I posted above, I want the layout to be like so:

26-05-2020
img 1, img 2, img 3

25-05-2020
img 1, img 2, img 3

etc. 

If I do it all by the latest images it becomes

26-05-2020
img 3, img 2, img 1

25-05-2020
img 3, img 2, img 1

etc. 

Please or to participate in this conversation.