---
title: "Reading & counting comments — Comments for Laravel | Roundly"
description: "Read comments through model relations or the fluent CommentQuery — filters, ordering, pagination, escape hatches and N+1-free counts."
url: https://roundly-consulting.com/open-source/docs/comments-for-laravel/reading-comments
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Comments for Laravel](https://roundly-consulting.com/open-source/docs/comments-for-laravel.md)

# Reading & counting comments

## Relations

```php
$post->comments;          // every comment written on the post
$post->approvedComments;  // visible + approved top-level comments, ordered per config
$user->writtenComments;   // every comment authored by the user

$comment->actor;          // the model that wrote the comment (null for anonymous)
$comment->commentable;    // the model the comment was written on
```

## The fluent query

Comments::query() returns a site-wide CommentQuery; Comments::for($subject) and Comments::byAuthor($author) return one already scoped — a read side that mirrors the write builder. Chain filters and ordering, then fetch:

```php
use RoundlyConsulting\Comments\Facades\Comments;

Comments::for($post)->approved()->newest()->paginate(20);
Comments::for($post)->visible()->rootsOnly()->withReplies()->get(); // public replies only
Comments::for($post)->pending()->count();
Comments::byAuthor($user)->get();
Comments::query()->hidden()->newest()->get();   // site-wide, every subject
```

withReplies() follows the query’s visibility: on a visible() query (in either order) only visible + approved replies load, at every level; without visible() every reply loads, for a moderation view.

| Method | Purpose |
| --- | --- |
| `for($subject) / byAuthor($author)` | Scope the query — they also chain onto Comments::query(). |
| `approved() / pending() / hidden()` | Filter by moderation status. |
| `visible()` | Visible flag on AND status approved. |
| `whereMeta($path, $value) / whereMetaMissing($path)` | Filter by your own metadata — see Comment metadata. |
| `rootsOnly()` | Top-level comments only. |
| `withReplies()` | Eager-load nested replies up to max\_depth — only visible + approved ones on a visible() query, every reply otherwise. |
| `newest() / oldest()` | Order by created\_at. |
| `orderByLikesDesc() / orderByTrending()` | Rank by likes — see Likes & ranking. |
| `mostReported() / reportedMoreThan() / withReportCounts()` | Moderation queues — see Reporting & auto-moderation. |
| `get() / paginate($perPage = 15) / count()` | Fetch, paginate or count the matches. |
| `approveAll() / hideAll() / deleteAll()` | Bulk moderation — see Moderation. |
| `tap($callback) / query()` | Refine or take the underlying Eloquent builder. |

## Escape hatches

When the built-in filters aren’t enough, tap() hands you the underlying Eloquent builder and query() returns it:

```php
Comments::for($post)
    ->visible()
    ->tap(fn ($query) => $query->where('created_at', '>=', now()->subWeek()))
    ->get();

$builder = Comments::for($post)->approved()->query(); // the underlying Builder<Comment>
```

## Comment counts

Show “X comments” on list pages without counting per row. Both helpers set a comments\_count attribute:

```php
$post->loadCommentCount();        // sets $post->comments_count

Post::withCommentCounts()->get(); // adds comments_count without N+1
```

comments\_count is what the public sees: every visible + approved comment on the subject, replies included — the same rows as Comment::visible(). Pending, hidden and visible(false) comments are never counted.

## Comment attributes

```php
$comment->comment;     // the body (stored in the `comment` column)
$comment->status;      // CommentStatus enum
$comment->visible;     // bool
$comment->parent_id;   // ?int — null for top-level comments
$comment->locked_at;   // ?Carbon — set when the thread under this comment is locked
$comment->meta;        // ?array — your own metadata, see Metadata
$comment->mentions;    // CommentMention rows
```

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/comments-for-laravel.md)
