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 Model Caching Laravel Package

miradnan/laravel-model-caching

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation: Run composer require miradnan/laravel-model-caching and publish the config (if needed) with php artisan vendor:publish --provider="miradnan\QueryCache\QueryCacheServiceProvider".
  2. Enable Caching: Add use miradnan\QueryCache\Traits\QueryCacheable; to your model and set $cacheFor (in seconds) to enable caching for all queries on that model.
    class Post extends Model {
        use QueryCacheable;
        public $cacheFor = 3600; // Cache for 1 hour
    }
    
  3. First Use Case: Test with a simple query:
    $posts = Post::where('published', true)->get();
    
    Verify cache hits by checking Laravel’s cache driver logs or using Cache::getStore()->get($cacheKey).

Implementation Patterns

Query-Level Caching

  • Dynamic Key Generation: The package auto-generates cache keys based on:
    • SQL query (e.g., SELECT * FROM posts WHERE published = 1).
    • Model class name (e.g., App\Models\Post).
    • Query parameters (e.g., where, orderBy, limit).
    • Example key: model:App\Models\Post:sql:SELECT * FROM posts WHERE published = 1.
  • Workflow:
    1. Query is executed.
    2. Result is cached with $cacheFor TTL.
    3. Subsequent identical queries return cached data.

Table-Level Caching (Bulk Operations)

  • Use TableCacheable trait for caching entire tables (e.g., Country::all()).
    class Country extends Model {
        use TableCacheable;
        public $cacheFor = 86400; // Cache for 24 hours
    }
    
  • Use Case: Ideal for read-heavy, rarely updated tables (e.g., country lists, static configurations).

Integration Tips

  • Cache Invalidation: Manually invalidate cache for a model/query using:
    Post::clearCache(); // Clears all cached queries for Post.
    Post::clearCacheForQuery('SELECT * FROM posts WHERE published = 1'); // Clears specific query.
    
  • Conditional Caching: Disable caching for specific queries by overriding shouldCache():
    public function shouldCache() {
        return !request()->has('nocache');
    }
    
  • Custom Cache Drivers: Configure the cache driver in config/query-cache.php (e.g., redis, database).
  • Debugging Queries: Enable SQL logging in .env:
    DB_LOG_QUERIES=true
    
    Check logs to verify cached vs. uncached queries.

Gotchas and Tips

Pitfalls

  1. Key Collisions:
    • Issue: Similar queries (e.g., where('id', 1) vs. find(1)) may generate different keys but cache the same data.
    • Fix: Normalize keys by overriding getCacheKey() in your model:
      protected function getCacheKey() {
          return 'normalized:key:' . md5($this->getTable() . serialize($this->getQuery()->getQuery()));
      }
      
  2. TTL Misconfiguration:
    • Issue: Setting $cacheFor too high can stale data. Too low increases DB load.
    • Tip: Use environment variables for flexibility:
      public $cacheFor = env('POST_CACHE_TTL', 3600);
      
  3. Eager Loading:
    • Issue: Cached queries with with() may not cache relationships correctly.
    • Workaround: Cache relationships separately or use load() after fetching cached data.
  4. Memory Usage:
    • Issue: Table-level caching (TableCacheable) loads entire tables into memory.
    • Tip: Use sparingly for large tables; prefer query-level caching.

Debugging

  • Cache Hits/Misses: Check Laravel’s cache store logs or add a debug method:
    protected function logCacheEvent($event) {
        \Log::debug("QueryCache [{$event}]: " . $this->getCacheKey());
    }
    
  • Key Inspection: Dump the cache key before queries:
    \Log::debug('Cache Key:', [
        'key' => Post::query()->where('published', true)->getCacheKey()
    ]);
    

Extension Points

  1. Custom Cache Tags:
    • Extend the trait to add cache tags for invalidation:
      use Illuminate\Support\Facades\Cache;
      protected function getCacheTags() {
          return ['posts:published'];
      }
      
    • Invalidate by tag: Cache::tags(['posts:published'])->flush().
  2. Query Modifiers:
    • Override getCachedQuery() to modify cached queries (e.g., add select clauses):
      protected function getCachedQuery() {
          return parent::getCachedQuery()->select(['id', 'title']);
      }
      
  3. Fallback Logic:
    • Implement handleCacheMiss() to run custom logic when cache misses:
      protected function handleCacheMiss() {
          // Custom logic (e.g., analytics, fallback data)
          return $this->newQuery()->get();
      }
      

Config Quirks

  • Default TTL: If $cacheFor is null, caching is disabled.
  • Cache Driver: Ensure the configured driver (e.g., file, redis) is available in config/cache.php.
  • Environment Overrides: Use .env to disable caching globally:
    QUERY_CACHE_ENABLED=false
    
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.
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
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope