Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Rating Laravel Package

cjmellor/rating

A Laravel package for adding ratings and reviews to your models. Supports polymorphic relationships, multiple rating types, and easy Eloquent integration, letting you attach star ratings or reviews to users, posts, products, and more.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package and publish its assets:

composer require cjmellor/rating
php artisan vendor:publish --tag="rating-config"
php artisan vendor:publish --tag="rating-migrations"
php artisan migrate

Add the Rateable trait to any model you want to be rateable:

use Cjmellor\Rating\Traits\Rateable;

class Post extends Model
{
    use Rateable;
}

First use case — the most common flow is a logged-in user rating a model:

$post->rate(5);                 // default rating type
$post->rate(4, 'star');        // explicit type
$post->averageRating();        // aggregate for display
$post->getRating();            // current user's rating

Where to look first: the published config/rating.php (defines your user_model and allowed rating_types) and app/Models for the trait wiring. Everything else is convention-driven off those two pieces.

Implementation Patterns

Rating types as a first-class concept. The package supports multiple independent rating dimensions on the same model (e.g. star, like, thumbs). Define them once in config and pass the type string through every call — rate, updateRating, unrate, getRating, averageRating all accept it. This is the cleanest way to support "rate the recipe" and "rate the plating" on the same record without separate tables.

Controller / Livewire action pattern. Typical mutation endpoint:

public function store(Request $request, Post $post)
{
    $post->rate($request->integer('value'), 'star');

    return back();
}

Use updateRating() rather than rate() if the user may already have a rating — it updates in place instead of relying on your own uniqueness guard.

Querying rated content. Use the provided scopes to avoid hand-rolling joins against the ratings table:

Post::whereRatedBy(auth()->user())->get();
Post::whereRated(auth()->user(), 5)->get();

Eager-load ratings when rendering lists that show per-item averages to avoid N+1 queries.

Displaying ratings. For quick UI, the package historically shipped a Livewire component. As of 2.2.0 it is optional — you must have livewire/livewire installed in your app to use it. If you don't want Livewire, treat averageRating() as a plain value and build your own Blade/JS widget around it.

Integration tips.

  • Bind the rating endpoint behind auth middleware — the trait implicitly associates the rating with auth()->user() (per your user_model config).
  • Cache averageRating() per model per type (e.g. via a computed column or Cache::remember) if you render it in listings; the method hits the database each call.
  • Seed rating types carefully: changing min/max after data exists won't retroactively validate old rows, only new writes.

Gotchas and Tips

  • Livewire is no longer a required dependency (2.2.0). If you're upgrading from 2.1.x and relied on the bundled Livewire component, confirm livewire/livewire is in your own composer.json. Without it, the rating UI component silently won't resolve.
  • Config caching. rating_types and user_model are read from config. After editing config/rating.php in production, run php artisan config:clear (or config:cache) or your changes won't take effect.
  • One rating per user per model per type. Calling rate() twice for the same user/type generally updates; if you need strict "no re-rating" behaviour, enforce it in a policy or Form Request rather than relying on the trait.
  • Polymorphic storage. Ratings live in a single morph table keyed by rateable_type/rateable_id. If you rename a model class or move namespaces, historical rows break. Keep a mapping migration ready when refactoring model names.
  • Value validation. The trait writes what you pass. Clamp/validate against your configured min/max in the request layer — the package won't reject an out-of-range integer for you on all paths.
  • Average precision. averageRating() returns a float. For display you'll want round($post->averageRating(), 1); storing the rounded value defeats the purpose of the aggregate.
  • Debugging. If rate() appears to do nothing, check: (1) the model actually uses Rateable, (2) a user is authenticated, (3) migrations ran, (4) the type string matches a key in rating_types. Wrong-type calls fail quietly rather than throwing in some versions.
  • Extension points. Subclass or decorate the Rate model via config if you need custom columns; publish migrations and add fields rather than editing vendor files. The trait is thin — overriding rate() in your model is a valid escape hatch for bespoke logic.
  • Laravel 11. 2.2.0 adds 11.x compatibility, so composer update is safe on L11 projects; pin to ^2.2 to guarantee the Livewire decoupling.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings