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 Cacheable Laravel Package

rinvex/laravel-cacheable

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require rinvex/laravel-cacheable
    

    Publish the config (optional):

    php artisan vendor:publish --provider="Rinvex\Cacheable\CacheableServiceProvider"
    
  2. Enable Caching for a Model: Add the Cacheable trait to your Eloquent model:

    use Rinvex\Cacheable\Cacheable;
    
    class Post extends Model
    {
        use Cacheable;
    }
    
  3. First Use Case: Cache a query result for 5 minutes:

    $posts = Post::cacheFor(5)->get(); // Automatically caches the query
    

Implementation Patterns

Core Workflows

  1. Granular Caching: Cache specific queries with conditions:

    $activePosts = Post::where('status', 'published')
        ->cacheFor(10)
        ->get();
    
  2. Fluent Integration: Chain caching with other query methods:

    $recentPosts = Post::orderBy('created_at', 'desc')
        ->take(10)
        ->cacheFor(15)
        ->get();
    
  3. Dynamic Cache Keys: Leverage query parameters (e.g., where, orderBy) to auto-generate cache keys:

    // Cache key: `posts_status_published_order_created_at_desc_limit_10`
    Post::where('status', 'published')
        ->orderBy('created_at', 'desc')
        ->take(10)
        ->cacheFor(30)
        ->get();
    
  4. Tag-Based Invalidation: Cache with tags for bulk invalidation:

    // Cache with tags
    Post::cacheFor(60, ['posts', 'published'])
        ->where('status', 'published')
        ->get();
    
    // Later, invalidate by tag
    Cache::tags(['posts'])->flush();
    
  5. Conditional Caching: Use cacheWhen for dynamic caching logic:

    $posts = Post::cacheWhen(
        fn() => request()->has('cache'),
        30
    )->get();
    

Advanced Patterns

  1. Custom Cache Drivers: Override the default driver in config/cacheable.php:

    'driver' => 'redis',
    
  2. Model-Level Defaults: Set defaults in the model:

    protected $cacheable = [
        'enabled' => true,
        'default_seconds' => 60,
        'tags' => ['posts'],
    ];
    
  3. Cache Events: Listen for cache events (e.g., CacheableCached, CacheableMissed):

    Cacheable::extend(function ($model) {
        Cacheable::onCached(function ($model, $key, $value) {
            // Log cache hits
        });
    });
    
  4. Fallback to Database: Use cacheFallback to fetch from DB if cache misses:

    $posts = Post::cacheFallback()->cacheFor(60)->get();
    

Gotchas and Tips

Common Pitfalls

  1. Key Collisions:

    • Issue: Complex queries with identical parameters may generate the same cache key, causing stale data.
    • Fix: Use cacheKey to manually specify a unique key:
      Post::cacheKey('custom_key')->cacheFor(60)->get();
      
  2. Tag Overhead:

    • Issue: Excessive tags can bloat cache storage and slow invalidation.
    • Tip: Limit tags to essential categories (e.g., ['posts', 'published']).
  3. TTL Misconfiguration:

    • Issue: Setting cacheFor(0) or negative values may cause unexpected behavior.
    • Fix: Validate TTL in your model or use a helper:
      protected function getCacheTtl(): int
      {
          return max(1, $this->cacheable['default_seconds'] ?? 60);
      }
      
  4. Eager Loading Quirks:

    • Issue: Caching relationships may not work as expected with with().
    • Workaround: Cache parent models separately or use load() after retrieval.
  5. Database vs. Cache Staleness:

    • Issue: Long TTLs may serve stale data if the underlying DB changes frequently.
    • Tip: Use shorter TTLs (e.g., 5–30 minutes) and implement background syncs if needed.

Debugging Tips

  1. Inspect Cache Keys: Dump the generated key to verify:

    $key = Post::where('status', 'published')->cacheKey();
    dd($key); // Debug the key structure
    
  2. Check Cache Contents: Use Laravel’s Cache::get() to verify stored data:

    dd(Cache::get($key));
    
  3. Log Cache Events: Enable logging for cache hits/misses:

    Cacheable::onCached(fn($model, $key, $value) => Log::debug("Cached: $key"));
    Cacheable::onMissed(fn($model, $key) => Log::debug("Missed: $key"));
    

Extension Points

  1. Custom Key Generators: Override getCacheKey() in your model:

    public function getCacheKey(): string
    {
        return "custom_prefix_" . parent::getCacheKey();
    }
    
  2. Dynamic TTL: Use a closure for dynamic TTLs:

    Post::cacheFor(fn() => request()->wantsJson() ? 300 : 60)->get();
    
  3. Pre-Caching: Pre-cache data during model events (e.g., retrieved):

    Post::retrieved(function ($post) {
        if (!$post->fresh) {
            $post->freshTimestamp();
            $post->cacheFor(300)->save();
        }
    });
    
  4. Fallback Logic: Extend CacheableFallback to customize fallback behavior:

    Cacheable::extend(function ($model) {
        $model->setCacheFallback(function () {
            return $model->newQuery()->with('relationship')->get();
        });
    });
    

Maintenance Notes

  • Abandoned Package: Since this package is unmaintained, consider:
  • Testing: Thoroughly test cache invalidation and edge cases (e.g., empty results, complex joins).
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.
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
renatovdemoura/blade-elements-ui