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 Eloquent Query Cache Laravel Package

rennokki/laravel-eloquent-query-cache

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require rennokki/laravel-eloquent-query-cache
    

    Publish the config (optional):

    php artisan vendor:publish --provider="RenokiCo\LaravelEloquentQueryCache\ServiceProvider"
    
  2. First Use Case: Cache a simple query for 5 minutes:

    use RenokiCo\LaravelEloquentQueryCache\Eloquent\Cacheable;
    
    class User extends Model
    {
        use Cacheable;
    }
    
    // In your controller/service:
    $users = User::where('active', true)->cacheFor(5)->get();
    
  3. Where to Look First:

    • README.md for basic usage.
    • config/eloquent-query-cache.php for configuration options.
    • src/Eloquent/Cacheable.php for the trait implementation details.

Implementation Patterns

Core Workflows

  1. Basic Caching:

    // Cache for 10 minutes
    $posts = Post::where('published', true)->cacheFor(10)->get();
    
    // Cache forever (until manually cleared)
    $tags = Tag::all()->cacheForever();
    
  2. Conditional Caching:

    // Only cache if the query has no constraints (e.g., `all()`)
    $allUsers = User::all()->cacheIfEmpty(300); // 5 minutes
    
  3. Tag-Based Invalidation:

    // Cache with tags for granular invalidation
    $products = Product::where('category', 'electronics')
        ->cacheFor(60, ['electronics', 'inventory'])
        ->get();
    
    // Later, invalidate by tags
    Cache::tags(['electronics'])->flush();
    
  4. Dependency-Based Invalidation:

    // Cache with dependencies (e.g., other models)
    $user = User::find(1)
        ->cacheFor(30, ['user:1'], fn() => User::with('posts')->find(1))
        ->get();
    
  5. Integration with Existing Code:

    • Replace direct Model::query()->get() calls with cached versions.
    • Use in repositories or services to abstract caching logic:
      class UserRepository {
          public function getActiveUsers() {
              return User::where('active', true)->cacheFor(30)->get();
          }
      }
      
  6. Dynamic Cache Keys:

    // Use a custom key generator
    $users = User::where('role', 'admin')
        ->cacheFor(60, null, fn() => "admin_users_{$this->tenantId}")
        ->get();
    

Advanced Patterns

  1. Caching Relationships:

    // Cache eager-loaded relationships
    $user = User::with('posts')->find(1)->cacheFor(30)->get();
    
  2. Partial Caching:

    // Cache only specific columns
    $user = User::select('id', 'name', 'email')
        ->cacheFor(10, null, fn() => "user:1:basic")
        ->first();
    
  3. Fallback Logic:

    // Use cached data if available, otherwise fetch fresh
    $data = Cache::remember('users_active', 30, function () {
        return User::where('active', true)->get();
    });
    
  4. Testing:

    • Mock the cache in tests:
      $this->partialMock(Cache::class, 'get');
      Cache::shouldReceive('get')->andReturn([]);
      

Gotchas and Tips

Pitfalls

  1. Cache Invalidation:

    • Forgetting to invalidate cache when data changes (e.g., after create, update, or delete).
    • Fix: Use tags or dependencies for invalidation:
      // Invalidate after update
      $user->update(['name' => 'New Name']);
      Cache::tags(['user:'.$user->id])->flush();
      
  2. Over-Caching:

    • Caching queries that return highly dynamic or rarely accessed data.
    • Fix: Use shorter TTLs or avoid caching for write-heavy models.
  3. Memory Leaks:

    • Caching large datasets (e.g., Model::all()) without pagination.
    • Fix: Limit results or use pagination:
      $users = User::paginate(20)->cacheFor(10)->get();
      
  4. Key Collisions:

    • Using generic keys (e.g., "users") for multiple queries.
    • Fix: Include query parameters in keys:
      ->cacheFor(60, null, fn() => "users_active_{$this->tenantId}")
      
  5. Relationship Caching:

    • Caching relationships that are frequently updated.
    • Fix: Cache relationships separately or use shorter TTLs.
  6. Configuration Conflicts:

    • Global cache settings overriding per-query settings.
    • Fix: Check config/eloquent-query-cache.php for defaults:
      'default_ttl' => 60, // seconds
      'use_tags' => true,
      

Debugging Tips

  1. Check Cache Hits/Misses:

    • Enable debug mode in config:
      'debug' => env('APP_DEBUG', false),
      
    • Log cache keys for troubleshooting:
      \RenokiCo\LaravelEloquentQueryCache\Cache::debug(true);
      
  2. Inspect Cache Storage:

    • Use Cache::getStore() to check stored keys:
      dd(Cache::store()->get('eloquent-query-cache:*'));
      
  3. Common Errors:

    • CacheableTrait not found: Ensure the trait is properly used in your model.
    • Serialization errors: Avoid caching complex objects (e.g., closures, resources). Use ->toArray() or ->jsonSerialize() if needed.

Extension Points

  1. Custom Cache Drivers:

    • Extend the package to support additional drivers (e.g., Redis clusters):
      // In ServiceProvider
      $this->app->extend('eloquent-query-cache.driver', function ($app) {
          return new CustomCacheDriver();
      });
      
  2. Event Listeners:

    • Listen for cache events (e.g., eloquent.query.cached):
      Event::listen('eloquent.query.cached', function ($model, $query, $cacheKey) {
          Log::info("Cached query for {$model} with key {$cacheKey}");
      });
      
  3. Middleware:

    • Create middleware to auto-cache queries in specific routes:
      public function handle($request, Closure $next) {
          if ($request->wantsJson()) {
              Cache::shouldCacheQueries(true);
          }
          return $next($request);
      }
      
  4. Testing Helpers:

    • Add helper methods to assert cache behavior:
      public function assertCached($model, $cacheKey) {
          $this->assertTrue(Cache::has($cacheKey));
      }
      
  5. Performance Tuning:

    • Adjust TTLs based on data volatility:
      // High volatility (e.g., stock prices)
      ->cacheFor(5)
      
      // Low volatility (e.g., static pages)
      ->cacheForever()
      
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.
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
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium