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

gwp's avatar
Level 2

Grouping by date, improvements needed

Hi.

I'm new to laraval, but loving it and laracasts!

I'd like to make a timeline, akin to the one we see on the profile pages on this forum, where there is a list of entries, which are grouped and separated by the date.

My Entry model is simple:

class Entry extends Model {

    protected $fillable = [
        'user_id',
        'body'
    ];

    /**
     * Each entry belongs to 1 user.
     */
    public function user()
    {
        return $this->belongsTo('App\User');
    }

}

I then grab the user-associated entries in my index() method:

$entries = $this->auth->user()->entries()->latest()->get();

Then in my view, I have something like this, which works:

    {!! $currentDay = 0 !!}
    @foreach ($entries as $entry)
        <?php
            $entryDate = Carbon\Carbon::parse($entry->created_at);
            if($entryDate->day !== $currentDay){
                $currentDay = $entryDate->day;
                echo "<hr> new day! {$currentDay} <br>";
            }
        ?>
        <li>{{ $entry->body }}</li>
    @endforeach

The problem is, is that this doesn't seem particularly laravel-like to me. Is there a better way to do this?

Thanks

0 likes
7 replies
davidfaux's avatar

Ideally you wouldn't want to have logic within your view however that is a task for another day :) Firstly Taylor has made timestamps so easy to use, in fact both created_at and updated_at are Carbon instances so $entry->created_at->day is already a valid call!

Here is how I would update this view:

{!! $currentDay = 0 !!}
@foreach($entries as $entry)
    {!! $entry->created_at->day !== $currentDay ? "<hr> new day! {$currentDay} <br>" : '' !!}
    <li>{{ $entry->body }}</li>
@endforeach

I haven't tested this but should produce the same results though

pmall's avatar
pmall
Best Answer
Level 56
$entries = $this->auth->user()->entries()->latest()->get();

$days = $entries->groupBy(function ($entry) {
    return $entry->created_at->day;
});
@foreach($days as $day => $entries)
    New day ! {{ $day }}
    @foreach($entries as $entry)
        {{ $entry->body }}
    @endforeach
@endforeach
gwp's avatar
Level 2

@dfaux Thanks! :)

@pmall I knew there must be a better way, this is awesome! I had a look at the groupBy docs but got a bit confused, your solution really helped!

Thanks both.

gwp's avatar
Level 2

@pmall I just realised, that the groupby function in your solution would separate out entries by day, but how would I do it by day AND month AND year? Essentially, how do i get each days entries separately?

pmall's avatar

Just format the created_at attribute as day-month-year in the callback

gwp's avatar
Level 2

Nevermind, just found that this works:

    $days = $entries->groupBy(function ($entry) {
        return $entry->created_at->toDateString();
    });

Please or to participate in this conversation.