---
title: "Ratings & aggregates — Reviews for Laravel | Roundly"
description: "Average rating, counts, star distribution and a RatingSummary DTO — live, approved-only aggregates on any subject."
url: https://roundly-consulting.com/open-source/docs/reviews-for-laravel/ratings-aggregates
language: en
---

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

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

# Ratings & aggregates

HasReviews gives every subject its relations and live aggregates. Aggregates count approved, top-level reviews only — pending, rejected and owner responses never move the score:

```php
$restaurant->reviews;                 // MorphMany (all rows, responses included)
$restaurant->topLevelReviews;         // MorphMany (owner responses excluded)
$restaurant->approvedReviews;         // approved, top-level only
$restaurant->averageRating();         // ?float, null when none
$restaurant->reviewsCount();          // int (all top-level, any status)
$restaurant->approvedReviewsCount();  // int (approved)
$restaurant->ratingDistribution();    // [5 => 120, 4 => 80, ...]
$restaurant->ratingSummary();         // RatingSummary DTO
```

| On the model (HasReviews) | On the facade | Counts |
| --- | --- | --- |
| `averageRating()` | `for($x)->average()` | Average of approved, top-level, rated reviews; null when none. |
| `approvedReviewsCount()` | `for($x)->count()` | Approved, top-level reviews (text-only included). |
| `ratingDistribution()` | `for($x)->distribution()` | Approved, rated reviews per rating value, highest first. |
| `ratingSummary()` | `for($x)->summary()` | All of the above plus photo counts, as a RatingSummary. |
| `reviewsCount()` | — | Every top-level review, whatever its status. |
| — | `for($x)->photoCount()` | Photos across approved, top-level reviews. |
| — | `for($x)->reviewsWithPhotos()` | Approved, top-level reviews with at least one photo. |

## The rating summary

ratingSummary() returns a RatingSummary DTO — everything a product page needs in one object, with toArray() for JSON responses:

```php
$summary = $restaurant->ratingSummary();

$summary->average;            // 4.6 (null when there are no rated reviews)
$summary->count;              // 320
$summary->distribution;       // [5 => 210, 4 => 80, 3 => 20, 2 => 6, 1 => 4]
$summary->photoCount;         // 57
$summary->reviewsWithPhotos;  // 41

return response()->json($summary->toArray());
// ['average' => 4.6, 'count' => 320, 'distribution' => [...],
//  'photo_count' => 57, 'reviews_with_photos' => 41]
```

- average ignores text-only reviews; count includes them.
- distribution is keyed by rating value, highest first, and only lists values that have at least one review.
- photoCount and reviewsWithPhotos are 0 when photos are disabled.

## On the facade

The same aggregates are available for any model through Reviews::for(), with or without the trait — the trait methods call it too:

```php
use RoundlyConsulting\Reviews\Facades\Reviews;

$reviews = Reviews::for($restaurant);

$reviews->average();                  // ?float, null when none
$reviews->count();                    // int (approved)
$reviews->distribution();             // [5 => 120, 4 => 80, ...]
$reviews->photoCount();               // total photos on approved reviews
$reviews->reviewsWithPhotos();        // approved reviews that carry a photo
$reviews->summary();                  // RatingSummary DTO — all of the above
```

Each call runs a query. For high-traffic listings, cache the count and average on the subject’s own table — see Cached aggregates.

## 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/reviews-for-laravel.md)
