Rating system for Laravel 8, 9, 10, 11 & 12.
composer require ghanem/ratingThe package uses Laravel's auto-discovery, so no need to manually register the service provider.
Publish and run the migration:
php artisan vendor:publish --provider="Ghanem\Rating\RatingServiceProvider"
php artisan migrateOptionally publish the config file:
php artisan vendor:publish --tag=rating-configAdd the Ratingable trait to any model you want to be ratable:
use Ghanem\Rating\Traits\Ratingable;
class Post extends Model
{
use Ratingable;
}Add the CanRate trait to the author model:
use Ghanem\Rating\Traits\CanRate;
class User extends Model
{
use CanRate;
}// From the ratable model
$rating = $post->rating(['rating' => 5], $user);
// From the author model
$rating = $user->rate($post, ['rating' => 5]);Only one rating per author per model:
$rating = $post->ratingUnique(['rating' => 5], $user);
// Or from the author
$rating = $user->rateUnique($post, ['rating' => 5]);$rating = $post->updateRating($ratingId, ['rating' => 3]);$post->deleteRating($ratingId);$post->rating([
'rating' => 5,
'body' => 'Great article!',
], $user);$restaurant->rating(['rating' => 5, 'type' => 'food'], $user);
$restaurant->rating(['rating' => 3, 'type' => 'service'], $user);
$restaurant->avgRating('food'); // 5.0
$restaurant->avgRating('service'); // 3.0
$restaurant->avgRating(); // 4.0 (all types)$post->rating(['rating' => 5, 'weight' => 2], $verifiedUser);
$post->rating(['rating' => 3, 'weight' => 1], $regularUser);
$post->weightedAvgRating(); // 4.33All aggregate methods accept an optional $type parameter for scoped ratings:
$post->avgRating() // average rating
$post->sumRating() // sum of all ratings
$post->countRatings() // total count
$post->countPositive() // count where rating > 0
$post->countNegative() // count where rating < 0
$post->ratingPercent() // percentage (default max: 5)
$post->ratingPercent(10) // percentage with custom max
$post->weightedAvgRating() // weighted averageAll available as attributes too:
$post->avgRating
$post->sumRating
$post->countRatings
$post->countPositive
$post->countNegative
$post->ratingPercent
$post->weightedAvgRating$user->hasRated($post); // bool
$user->getRating($post); // Rating|null
$user->averageGivenRating(); // float
$user->totalGivenRatings(); // int
$user->ratings; // all ratings given$post->isRatedBy($user); // bool
$post->isRatedBy($user, 'food'); // bool (scoped)// Eager load rating aggregates
Post::withAvgRating()->get();
Post::withSumRating()->get();
Post::withCountRatings()->get();
// Order by ratings
Post::orderByAvgRating()->get(); // desc by default
Post::orderByAvgRating('asc')->get();
Post::orderBySumRating()->get();
Post::orderByCountRatings()->get();
// Filter by minimum rating
Post::minAvgRating(3.5)->get();
Post::minSumRating(10)->get();
// Scoped by type
Post::withAvgRating('food')->get();
Post::orderByAvgRating('desc', 'food')->get();Configure rating bounds in config/rating.php:
return [
'min' => 1,
'max' => 5,
'allow_negative' => false,
];Invalid ratings throw Ghanem\Rating\Exceptions\InvalidRatingException.
The package fires events on rating lifecycle:
Ghanem\Rating\Events\RatingCreatedGhanem\Rating\Events\RatingUpdatedGhanem\Rating\Events\RatingDeleted
Each event has a public $rating property with the Rating model.
composer test