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

Rahul's avatar
Level 1

Best way to paginate relations in laravel

Hi i'm building a websites which have posts and option to make comments to that posts. but i stuck into a problem, here is the problem with scenario -

  1. One post can have many comments.
  2. so i can simply defined that relationship in laravel and fetch with query like this : Post::with('comments')->paginate(10); with other conditions. But now-
  3. what if a post can have 100 or 1000 of comments . this approach is simply horrible for many reasons . that query will kill me.

So what i want -

  1. how can i paginate those comments by 10 or so . and give user facility to read more comments and when they click on that link then next 10 comments will show on the list for that post and so on.. this will increase performance and even prevent me to look ugly.

How can we do that in laravel .. please help. Your help will be much appreciated

0 likes
9 replies
edoc's avatar

@Rahul why dont you fetch separately?

like

public function show($id)
    {
        $topic = Topic::where('id',$id)->firstOrFail();

        $comments = Comment::where('topic_id', $id)->with('user')->paginate(15);

        return view('forums.show', compact('topic', 'comments'));
    }
Rahul's avatar
Level 1

@edoc - Basically i'm building API with laravel and calling with my client angular application . well this is fine for getting first 15 comments for all post according to your code. but what about other comments . when request for more comments for that single post . for that i should need to build other function or something like that. what would you like to say on that topic.?

JeroenVanOort's avatar

I'd make a separate endpoint for comments. For example, you could use /api/v1/posts to get the post's ID, and then make a second call to /api/v1/comments?post_id=42. In this second call, you can do any pagination you want, including getting more records if the user clicks that button.

2 likes
edoc's avatar

<<well this is fine for getting first 15 comments for all post according to your code

I'm afraid no sir.You can fetch all the comments since every comment is paginated

Let's say you have this code for your api

public function fetch(){

        return App\Comment::paginate(5);
}

and let's say you have 20 comments for the particular post. that will be 4 pages in total right?

when you access like api/comments/{id} you fetch the first 5 comments

and then you wanna fetch the next 5 you hit api/comments/{id}/?page=2

Rahul's avatar
Level 1

Ok edoc , i might be wrong :). let me give it a shot and then i'll be back.

yes i know that. even i fetched all my posts from databases and even added infinite scroll feature to my frontend :) . but i'm little careful about comments. n i were stuck. but now i have found couple way to solve it. let me try

Rahul's avatar
Level 1

Thanks JeroenVanOort. i think your endpoint gave me another way to think about the solution of this problem. let me see which one works for me better.

kfirba's avatar

@Rahul you can also use nested resources endpoint:

/posts/{post}/comments

Rahul's avatar
Rahul
OP
Best Answer
Level 1

So here is the perfect ans of my own question -

Whenever we think of loading related data , the first things came into mind is by using laravel eloquent eager loading . like : In my case i wants to load Post with it's Comments, so with eager loading we write something like this

$posts = Post::with('comments')->paginate(10);   OR
$posts = $this->post->with('comments')->paginate(10); OR

In this case it's really hard to paginate comment and if we can do by nested query. it's really hard to make next page request on that comment.

but this was not the right way to do it. yeah this was first cam into mind.. so

Solution

so basically what i did, i just wanted to show my users initially single comment for that i fetched my post with single & most popular comment. like this: end point is: /posts

$posts = $this->post->with(['comments'=> function(query){

   $query->first();   //your popular comment or other logic

}])->paginate(10);

this was initial comment for my post.

then i created new function for handling my asynchronous fetching comments. like @edoc said :

end point is: posts/postId/comments @kfirba said

public function getPostComments($postId)
    {
        $post= Post::where('id',$id)->firstOrFail();

        $comments = Comment::where('post_id', $postId)->with('user')->paginate(15);

        return view('post.show', compact('post', 'comments'));
    }

So now you can call this function for your paginated comments.

Taught , it will be awesome to explain this for someone else, Thanks to @edoc @kfirba & @JeroenVanOort

13 likes

Please or to participate in this conversation.