## Getting Started
### Minimal Setup
1. **Installation**:
```bash
composer require rennokki/rating
php artisan vendor:publish --provider="Rennokki\Rating\RatingServiceProvider" --tag="migrations"
php artisan migrate
ratings table.Model Integration:
Use the HasRatings trait in your Eloquent model:
use Rennokki\Rating\Traits\HasRatings;
class Product extends Model
{
use HasRatings;
}
First Use Case:
Product with ID 1):
$product = Product::find(1);
$product->rate(4); // 4 stars
$average = $product->ratingAverage();
$count = $product->ratingCount();
Where to Look First:
config/rating.php for customization (e.g., rating scale, allowed users).database/migrations/ for schema details (e.g., rating table structure).Rating Assignment:
$model->rate($stars); // e.g., 1-5
$model->rate(5, ['user_id' => auth()->id(), 'comment' => 'Great product!']);
$model->rateMultiple([4, 5, 3]); // Assigns multiple ratings at once.
Querying Ratings:
$topRated = Product::withHighestRating()->limit(10)->get();
$model->ratings()->where('user_id', auth()->id())->get();
$model->ratingAverage(); // Float
$model->ratingCount(); // Integer
$model->ratingSum(); // Total sum of all ratings
Validation and Constraints:
config/rating.php:
'scale' => [1, 2, 3, 4, 5], // Default: 1-5
'allowed_users' => ['admins', 'members'], // Uses Laravel gates/policies.
Integration with Existing Logic:
rating.created or rating.updated events to trigger side effects (e.g., notifications, analytics).
event(new RatingCreated($rating));
Rating model observer to add custom logic (e.g., log ratings to a third-party service).API Responses:
public function toArray($request)
{
return [
'id' => $this->id,
'rating' => $this->ratingAverage(),
'count' => $this->ratingCount(),
];
}
Testing:
HasRatings trait to test rating logic in isolation.Migration Conflicts:
ratings table (e.g., add columns), ensure your migrations don’t conflict with the package’s default schema. Extend the create_ratings_table migration instead of replacing it.Schema::table('ratings', function (Blueprint $table) {
$table->string('custom_field')->nullable();
});
Rating Scale Mismatch:
config/rating.php, ensure your frontend and database logic align. For example, a scale of [1, 3, 5] will reject ratings like 2 or 4.$validated = $request->validate([
'stars' => ['required', 'integer', Rule::in(config('rating.scale'))],
]);
Performance with Large Datasets:
ratingAverage() or ratingCount() on models with millions of ratings can be slow. Use database indexes or caching.ratings table:
Schema::table('ratings', function (Blueprint $table) {
$table->index('ratable_id');
});
Or cache results:
$cacheKey = "rating_avg_{$model->id}";
$average = Cache::remember($cacheKey, now()->addHours(1), function () use ($model) {
return $model->ratingAverage();
});
Duplicate Ratings:
user_id or ip_address). If you need to allow updates, override the canRate method in your model:
public function canRate($attributes)
{
return true; // Allow any rating, even duplicates.
}
Soft Deletes:
ratable model uses soft deletes, ensure the ratings table also supports them. The package doesn’t enable this by default.softDeletes to the Rating model and update migrations:
use Illuminate\Database\Eloquent\SoftDeletes;
class Rating extends Model
{
use SoftDeletes;
}
Foreign Key Constraints:
ratings table assumes a ratable_id foreign key. If your model uses a different key (e.g., product_id), override the getRatingsQuery method:
public function getRatingsQuery()
{
return $this->ratings()->where('product_id', $this->id);
}
Log Rating Events: Use Laravel’s logging to debug rating assignments:
\Log::info('Rating assigned', ['model' => $model->id, 'stars' => $stars, 'metadata' => $metadata]);
Check Database Triggers:
If ratings aren’t saving, verify the ratings table exists and the ratable_id column matches your model’s primary key.
Validate Config:
Ensure config/rating.php is correctly published and merged. Run:
php artisan config:clear
to reset cached config.
Test with Tinker: Quickly test rating logic in Tinker:
php artisan tinker
$product = App\Models\Product::first();
$product->rate(5);
$product->ratingAverage(); // Check output
Custom Rating Logic:
Override the rate method in your model to add pre/post-processing:
public function rate($stars, $metadata = [])
{
$this->beforeRating($stars, $metadata);
parent::rate($stars, $metadata);
$this->afterRating();
}
Dynamic Rating Scales:
Make the rating scale dynamic per model by overriding getRatingScale:
public function getRatingScale()
{
return [1, 2, 3]; // Custom scale for this model.
}
Third-Party Integrations:
Extend the Rating model to sync with external services (e.g., Google Reviews):
class Rating extends \Rennokki\Rating\Models\Rating
{
protected static function booted()
{
static::created(function ($rating) {
// Sync to external API.
});
}
}
Custom Rating Models:
Use the HasRatings trait with a custom rating model by binding it in the service provider:
$this->app->bind(
\Rennokki\Rating\Contracts\Rating::class,
\App\Models\CustomRating::class
);
Localization: Customize rating labels (e.g., "Poor", "Excellent") by extending the package’s language files or using a helper:
How can I help you explore Laravel packages today?