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

RachidLaasri's avatar

How to achieve this, eloquent tricks

Hi everyone,

So, i have posts tables and i want to group them by the date in this format :

  • Tuesday April 14
    • Post
    • Post
  • Wednesday April 15
    • Post
    • Post

But with pagination, i tried grouping by date format(l) but it doesn't work with pagination.

Any help would be much appreciated.

0 likes
17 replies
toniperic's avatar

This is the closest I could get for ordering posts by date.

Raw

select *, date(created_at) as date_of_creation from posts order by date_of_creation

Eloquent

Post::select('*')->selectRaw('date(created_at) as date_of_creation')->orderBy('date_of_creation');

Not sure how you intended to group them by days, since each record is represented as one row in the table.

RachidLaasri's avatar

I am currently using this, but it's not working with pagination...

Post::latest()
            ->get()
            ->groupBy(function($date) {
                return Carbon::parse($date->created_at)->format('l');
            });
toniperic's avatar

What you get in your call is a Collection object if I'm not mistaken, and you're free to pass the Collection as the first argument to the Paginator. Notice line 40.

@RachidLaasri how exactly is it not working for you? What output do you get?

RachidLaasri's avatar

I think the problem is using "get" method before grouping.

The error i get when i try to add the groupBy clause is :

Call to undefined method Illuminate\Database\Eloquent\Collection::paginate()
toniperic's avatar

@RachidLaasri it's because get() method returns a Collection instance, and there's no paginate() method on Collection instance. The groupBy() you're calling is actually performed on the Collection instance, after all of the data has been loaded.

Since paginate() method on the Eloquent model returns a LengthAwarePaginator instance, can't you do the same?

$data = Post::latest()
    ->get()
    ->groupBy(function($date) {
        return Carbon::parse($date->created_at)->format('l');
    });

return new LengthAwarePaginator($data, /** other params */);
unglued's avatar

Why you do not want group it with pure PHP after SQL query and pagination?

RachidLaasri's avatar

@JarekTkaczyk i didn't understand what you meant, what i want to do is show the posts on the home page, i want the user to be able to see the posts grouped by days with pagination, from newest to oldest...

pmall's avatar

@toniperic solution should work. Creating a grouped collection and instanciate a LengthAwarePaginator.

JarekTkaczyk's avatar
Level 53

@RachidLaasri Well, I asked what's the pagination base. You said the date, so I suppose this:

  1. you want N dates per page, no matter how many posts there are for each date
  2. you want N dates with posts, not N consecutive dates

That said, you want to first get the N dates (distinct) ordered desc, then you get the real result - your posts, that were published on that N dates. Next, you just group the result collection by date and you're good. Should I explain it in code?

RachidLaasri's avatar

@SachinAgarwal Yes, the same idea as a timeline.

@pmall I tried it, still giving me all the posts ( the pagination doesn't work ).

@JarekTkaczyk Thanks for the explanation, it would be better if you could explain it in code...

JarekTkaczyk's avatar

@RachidLaasri Assuimng MySQL and created_at timestamp as your field (if you're using date type, then no need for raw additions):

$dates = Post::selectRaw('date(created_at) as date')->latest()->distinct()->paginate()->lists('date');

$posts = Post::whereIn(DB::raw('date(created_at)'), $dates)->get()->groupBy( YOUR CLOSURE HERE );

Please or to participate in this conversation.