Weave Code
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

rennokki/rating

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**:
   ```bash
   composer require rennokki/rating
   php artisan vendor:publish --provider="Rennokki\Rating\RatingServiceProvider" --tag="migrations"
   php artisan migrate
  • Publishes migrations and config. Run migrations to create the ratings table.
  1. Model Integration: Use the HasRatings trait in your Eloquent model:

    use Rennokki\Rating\Traits\HasRatings;
    
    class Product extends Model
    {
        use HasRatings;
    }
    
  2. First Use Case:

    • Assign a rating to a model (e.g., Product with ID 1):
      $product = Product::find(1);
      $product->rate(4); // 4 stars
      
    • Get average rating for a model:
      $average = $product->ratingAverage();
      
    • Count ratings:
      $count = $product->ratingCount();
      
  3. Where to Look First:

    • README for core features.
    • config/rating.php for customization (e.g., rating scale, allowed users).
    • database/migrations/ for schema details (e.g., rating table structure).

Implementation Patterns

Core Workflows

  1. Rating Assignment:

    • Basic Usage:
      $model->rate($stars); // e.g., 1-5
      
    • With Metadata (e.g., user ID, IP, or custom data):
      $model->rate(5, ['user_id' => auth()->id(), 'comment' => 'Great product!']);
      
    • Bulk Rating:
      $model->rateMultiple([4, 5, 3]); // Assigns multiple ratings at once.
      
  2. Querying Ratings:

    • Filter Models by Rating:
      $topRated = Product::withHighestRating()->limit(10)->get();
      
    • Scope Ratings:
      $model->ratings()->where('user_id', auth()->id())->get();
      
    • Aggregate Functions:
      $model->ratingAverage(); // Float
      $model->ratingCount();   // Integer
      $model->ratingSum();     // Total sum of all ratings
      
  3. Validation and Constraints:

    • Custom Rating Scale: Configure in config/rating.php:
      'scale' => [1, 2, 3, 4, 5], // Default: 1-5
      
    • Restrict Ratings by User:
      'allowed_users' => ['admins', 'members'], // Uses Laravel gates/policies.
      
  4. Integration with Existing Logic:

    • Events: Listen for rating.created or rating.updated events to trigger side effects (e.g., notifications, analytics).
      event(new RatingCreated($rating));
      
    • Observers: Extend the Rating model observer to add custom logic (e.g., log ratings to a third-party service).
  5. API Responses:

    • Serialize Ratings: Use Laravel's resource classes to format responses:
      public function toArray($request)
      {
          return [
              'id' => $this->id,
              'rating' => $this->ratingAverage(),
              'count' => $this->ratingCount(),
          ];
      }
      
  6. Testing:

    • Unit Tests: Mock the HasRatings trait to test rating logic in isolation.
    • Feature Tests: Use Laravel's HTTP tests to verify rating flows (e.g., submitting a rating via a form).

Gotchas and Tips

Pitfalls

  1. Migration Conflicts:

    • If you customize the 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.
    • Fix: Use a custom migration that extends the package’s table:
      Schema::table('ratings', function (Blueprint $table) {
          $table->string('custom_field')->nullable();
      });
      
  2. Rating Scale Mismatch:

    • The package defaults to a 1-5 scale. If you change this in 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.
    • Fix: Validate input on the frontend and backend:
      $validated = $request->validate([
          'stars' => ['required', 'integer', Rule::in(config('rating.scale'))],
      ]);
      
  3. Performance with Large Datasets:

    • Querying ratingAverage() or ratingCount() on models with millions of ratings can be slow. Use database indexes or caching.
    • Fix: Add an index to the 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();
      });
      
  4. Duplicate Ratings:

    • The package prevents duplicate ratings by the same user (via 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.
      }
      
  5. Soft Deletes:

    • If your ratable model uses soft deletes, ensure the ratings table also supports them. The package doesn’t enable this by default.
    • Fix: Add softDeletes to the Rating model and update migrations:
      use Illuminate\Database\Eloquent\SoftDeletes;
      
      class Rating extends Model
      {
          use SoftDeletes;
      }
      
  6. Foreign Key Constraints:

    • The 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);
      }
      

Debugging Tips

  1. Log Rating Events: Use Laravel’s logging to debug rating assignments:

    \Log::info('Rating assigned', ['model' => $model->id, 'stars' => $stars, 'metadata' => $metadata]);
    
  2. Check Database Triggers: If ratings aren’t saving, verify the ratings table exists and the ratable_id column matches your model’s primary key.

  3. Validate Config: Ensure config/rating.php is correctly published and merged. Run:

    php artisan config:clear
    

    to reset cached config.

  4. Test with Tinker: Quickly test rating logic in Tinker:

    php artisan tinker
    
    $product = App\Models\Product::first();
    $product->rate(5);
    $product->ratingAverage(); // Check output
    

Extension Points

  1. 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();
    }
    
  2. 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.
    }
    
  3. 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.
            });
        }
    }
    
  4. 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
    );
    
  5. Localization: Customize rating labels (e.g., "Poor", "Excellent") by extending the package’s language files or using a helper:

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.
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver