unixlab's avatar

Nested comments pagination doesn't work properly

Hi everyone Following this tutorial https://laracasts.com/series/how-do-i/episodes/9

I created a single level nested comments and also added pagination.

  • Comment
  • Child comment
  • Child comment
  • Child comment

If i say 2 comments per page then the result becomes

  • Comment
  • Child comment

Do you see what's happening here? I want the pagination to work only for the top-level comments

Does anybody have any idea how to fix this issue?

0 likes
12 replies
Nakov's avatar

@unixlab can you please share the code that you are using?

Do you have something like this for example:

Comment::with('replies')->paginate(2);

?

unixlab's avatar

Yeah sure

$this->comments->approved($storyId)->groupBy('parent_id');

That's how i get the comments for the specific article

As you can see i'm grouping the comments using the Collection's groupBy method

Nakov's avatar

@unixlab but then this one does not show how do you apply a pagination. If you applied a pagination on the grouped results, then for sure you will get just two results back.

How is your relationship setup between a Comment and a Child comment. Share more code please, from the view, the model..

unixlab's avatar

I'm using the laravel paginate() method. I'm also using repositories

That's how im getting the comments in the repository

    public function approved($storyId)
    {
        $this->query = Comment::where(['story_id' => $storyId, 'approved' => 1]);
        return $this->paginate();
    }

    public function paginate()
    {
        return $this->query->paginate(config('site.comments_per_page'), ['*'], 'p');
    }
Nakov's avatar

@unixlab I guess I will have to ask for each code block separately.. if you re-read my reply above I asked for much more than just the pagination. I don't know how is your relationship setup between a Comment and a Child comment.. How do you differentiate a comment from a child comment?

With what you have shown tells me that you just want to take two results from the comments, not including any child comments, and in your case the comments and child comments are at the same level, which means you might display them using some conditions or a separate query in the view..

So either you share all the code that is involved for displaying the comments, or you find your way around it alone taken what I am saying here :)

unixlab's avatar

There's no actual relationship between the Comment and a Child comment.

https://laracasts.com/series/how-do-i/episodes/9

You just setup a basic hasMany relationship

Model

    public function comments()
    {
        return $this->hasMany('App\Comment');
    }

After you grab the comments with

$comments = $this->comments->approved($storyId);

You are grouping them with the help of groupBy()

i.e.

$comments->groupBy('parent_id');

That's Jeffrey's way to achieve nested comments.

I hope this helps

Nakov's avatar
Nakov
Best Answer
Level 73

@unixlab okay so there is a parent_id that's how the child is connected to a parent.. His way is a bit different, he structures the tree on an instance of the collection, that's why you get two results only..

I would do the following, in the Comment model, add this for example:

public function replies() {
    return $this->hasMany(Comment::class,'parent_id','id') ;
}

Then this query:

Comment::with('replies')->where('post_id', $postId)->whereNull('parent_id')->paginate(2);

Should select just 2 comments from the post with their replies.

Nakov's avatar

@unixlab nope. with() is used to eager load the relationship. Which means reduced number of queries. Unless you use with() then yes, calling $comment->replies will perform another query

unixlab's avatar

@nakov that's how im loopin thru the child comments

    @if (!empty($comment->replies))
        @foreach ($comment->replies as $subcomment)
            @include('comments.comment', ['comment' => $subcomment, 'isReply' => false])
        @endforeach
    @endif

And one more thing if you don't mind. Now works perfectly except the fact child comments will not have any pagination at all. So in the feature if i want to paginate the subcomments what are my options ?

Nakov's avatar

@unixlab yes, but after using with() calling $comment->replies uses the eager loaded collection won't do an extra query no worries here.

To me it does not make sense to have a pagination on the replies, you might need a JavaScript for this for example, to show the latest two replies and then a Load more button, but that will all be scripted I guess, instead of using the Query Builder in this case only as it will look odd having a pagination links for both comments and replies.

Please or to participate in this conversation.