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

Laravel Reactions Laravel Package

webotvorba/laravel-reactions

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require webotvorba/laravel-reactions
    

    Publish the migration and config:

    php artisan vendor:publish --provider="Webotvorba\LaravelReactions\LaravelReactionsServiceProvider" --tag="migrations"
    php artisan vendor:publish --provider="Webotvorba\LaravelReactions\LaravelReactionsServiceProvider" --tag="config"
    

    Run migrations:

    php artisan migrate
    
  2. Configure Models: Add the HasReactions trait to your Eloquent model (e.g., Post.php):

    use Webotvorba\LaravelReactions\HasReactions;
    
    class Post extends Model
    {
        use HasReactions;
    }
    
  3. First Use Case: Add a reaction to a model instance:

    $post = Post::find(1);
    $post->react('👍'); // Add a reaction
    

    Fetch reactions for a model:

    $reactions = $post->reactions; // Collection of reactions
    $count = $post->reactionCount('👍'); // Count for a specific emoji
    

Implementation Patterns

Core Workflows

  1. Adding/Removing Reactions:

    // Add a reaction (creates or increments)
    $model->react('😂');
    
    // Remove a reaction (decrements or deletes)
    $model->unreact('👍');
    
    // Toggle reaction (adds if missing, removes if exists)
    $model->toggleReaction('❤️');
    
  2. Querying Reactions:

    // Get all reactions for a model
    $model->reactions;
    
    // Get reaction count for a specific emoji
    $model->reactionCount('👍');
    
    // Check if a user reacted
    $model->hasReacted('😂', auth()->id());
    
  3. Custom Reaction Types: Extend the Reaction model to add custom fields (e.g., created_at for timestamps):

    class CustomReaction extends \Webotvorba\LaravelReactions\Models\Reaction
    {
        protected $table = 'custom_reactions';
    }
    

    Update the config to use your custom model:

    'model' => \App\Models\CustomReaction::class,
    
  4. Frontend Integration: Use Blade directives to render reactions:

    @reactions($post)
        <button data-reaction="{{ $reaction }}">
            {{ $reaction }} ({{ $post->reactionCount($reaction) }})
        </button>
    @endreactions
    

    JavaScript (e.g., Alpine.js) to handle toggling:

    document.querySelectorAll('[data-reaction]').forEach(button => {
        button.addEventListener('click', () => {
            const reaction = button.dataset.reaction;
            axios.post(`/posts/${postId}/react`, { reaction });
        });
    });
    
  5. API Endpoints: Create a controller method to handle reactions:

    public function react(Request $request, Post $post)
    {
        $post->toggleReaction($request->reaction);
        return response()->json(['success' => true]);
    }
    

    Add a route:

    Route::post('/posts/{post}/react', [PostReactionController::class, 'react']);
    

Gotchas and Tips

Pitfalls

  1. Migration Conflicts:

    • If the reactions table already exists, manually adjust the migration or drop the table before re-running migrations.
    • Ensure the reactionable_id and reactionable_type columns are correctly set up for polymorphic relations.
  2. Caching Reactions:

    • The package does not cache reactions by default. For high-traffic apps, cache reaction counts using Laravel's cache:
      $count = Cache::remember("reactions_{$model->id}_{$emoji}", now()->addHours(1), function() use ($model, $emoji) {
          return $model->reactionCount($emoji);
      });
      
  3. Duplicate Reactions:

    • By default, the package prevents duplicate reactions from the same user. If you need to allow multiple reactions per user, override the react method in your model:
      public function react($emoji, $userId = null)
      {
          $userId = $userId ?: auth()->id();
          $this->reactions()->updateOrCreate(
              ['user_id' => $userId, 'emoji' => $emoji],
              ['emoji' => $emoji]
          );
      }
      
  4. Performance with Large Datasets:

    • Avoid eager-loading reactions for models where reactions are not immediately needed. Use withReactions only when necessary:
      $posts = Post::withReactions()->get(); // Only if you need reactions for all posts
      
  5. Custom Validation:

    • Validate reactions in your controller or form requests to ensure only allowed emojis are used:
      public function rules()
      {
          return [
              'reaction' => ['required', 'string', Rule::in(['👍', '👎', '😂', '❤️'])]
          ];
      }
      

Debugging Tips

  1. Check Database:

    • Verify the reactions table has the expected columns (user_id, emoji, reactionable_id, reactionable_type).
    • Run php artisan tinker to test reactions directly:
      $post = App\Models\Post::find(1);
      $post->react('👍');
      $post->reactions()->get();
      
  2. Log Queries: Enable Laravel's query logging to debug issues:

    DB::enableQueryLog();
    $post->react('👍');
    dd(DB::getQueryLog());
    
  3. Event Listeners:

    • Listen for reaction events to trigger custom logic (e.g., notifications):
      public function boot()
      {
          \Webotvorba\LaravelReactions\Events\ReactionAdded::class => function ($event) {
              Notification::send($event->model->user, new ReactionNotification($event->reaction));
          };
      }
      

Extension Points

  1. Custom Reaction Models:

    • Extend the Reaction model to add metadata (e.g., ip_address, device):
      class Reaction extends \Webotvorba\LaravelReactions\Models\Reaction
      {
          protected $fillable = ['ip_address', 'device'];
      }
      
    • Update the migration to include new columns.
  2. Reaction Scopes:

    • Add scopes to filter models by reactions:
      public function scopeWithReaction($query, $emoji)
      {
          return $query->whereHas('reactions', function($q) use ($emoji) {
              $q->where('emoji', $emoji);
          });
      }
      
      Usage:
      $posts = Post::withReaction('👍')->get();
      
  3. Reaction Aggregates:

    • Create a custom accessor to get top reactions:
      public function getTopReactionsAttribute()
      {
          return $this->reactions()->groupBy('emoji')
              ->select('emoji', DB::raw('COUNT(*) as count'))
              ->orderBy('count', 'desc')
              ->get();
      }
      
  4. Reaction Policies:

    • Use Laravel's authorization to restrict reactions (e.g., only logged-in users):
      public function react(Post $post)
      {
          $this->authorize('react', $post);
          $post->react($request->reaction);
      }
      
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.
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
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours