github mike-bronner/laravel-model-caching 13.2.0

4 hours ago

πŸ’₯ Breaking Changes

1. PHP 8.2 is no longer supported

13.2.0 requires PHP 8.3 or later (#645). On PHP 8.2, Composer stays on 13.1.11.

2. $isCachable is typed bool

The trait now declares protected bool $isCachable (#647). A model or builder that declares $isCachable again without the bool type fails with a fatal error when the class loads.
Fix: declare it as protected bool $isCachable.

3. The trait no longer has newBaseQueryBuilder()

13.1.8 added newBaseQueryBuilder() to the Cachable trait. It collided with other traits that define the same method, such as CTE support, so it is gone (#640, #651). A trait rule that names Cachable::newBaseQueryBuilder now fails when the class loads:

  • Cachable::newBaseQueryBuilder as ...
  • Cachable::newBaseQueryBuilder insteadof ...

Fix: delete that rule. Other::newBaseQueryBuilder insteadof Cachable still works.

4. modelCache:clear no longer empties the whole cache store

On Redis, the command used to wipe the app's entire cache store, or the whole Redis database when the prefix was empty (#645). It now deletes only the package's own entries.
Fix: if a script relied on it to clear everything, add php artisan cache:clear.

5. Some cache keys and tags change

These queries miss the cache once after upgrading, then rebuild:

  • Closure where(), orWhere() and whereNot() queries on models with global scopes (#647).
  • morphTo eager loads onto models with global scopes (#647).
  • withoutGlobalScopesExcept() calls that keep every scope (#647).
  • Eager-load constraints that do more than add where clauses (#647).
  • belongsToMany and morphToMany queries onto scoped models, or that use withPivot(), withTimestamps(), a custom as(), using(), with(), or a related model with $with (#647).
  • fromSub(), union and beforeQuery() bindings that are Stringable objects with non-public state (#647).
  • Eager loads of a belongsToMany or morphToMany relation that do not join the pivot table, such as with('stores') (#641, #653).
  • Through-relation queries that use with() (#647), or that forward a macro or custom builder method (#656).
  • Every macro or custom builder method call with arguments (#656). The arguments now key as a JSON list, because null, false and "" used to share a key, as did 1 and "1".
  • Cool-down keys on models that declare $cachePrefix (#651). A cool-down window that is open at upgrade ends early once.

6. Some queries now run uncached

These used to be cached under a key that another query could share, so they could return the wrong rows. They now always read from the database:

  • A where() or having() value that cannot be keyed reliably, such as an object serialize() rejects or a value that holds a resource (#647).
  • An eager-load constraint with an afterQuery() callback (#647).
  • A relation query that eager-loads a model without Cachable (#647).
  • A macro or custom builder method that gets a closure, an object without __toString(), or an array json_encode cannot encode (#656).

⬆️ Upgrade steps

  1. Run php artisan modelCache:clear after you deploy. Some changed queries keep their old key text, so until the next write to that table they could read an entry the old version wrote.
  2. Check your models for an untyped $isCachable and for trait rules that name newBaseQueryBuilder (items 2 and 3).

Changes

Added

  • feat: ⏰ Add global and per-model TTL caching options by @MonikaJov in #637

Fixed

  • πŸ› Correct cache invalidation and describe the package to consuming agents. by @mikebronner in #645
  • πŸ› Build a cache key for a where() value of any type by @bastianschwarz in #629
  • πŸ› Memoize the morphTo type lookup instead of running it per tag set by @bastianschwarz in #630
  • πŸ› Tag the tables a where-subquery joins, not only the one it selects from by @bastianschwarz in #631
  • πŸ› Build a cache key for a query whose from is a subquery by @bastianschwarz in #633
  • πŸ› Resolve every #646 review point and the cache-key gaps behind them by @mikebronner in #647
  • πŸ› Resolve the cache TTL from eager loads and validate it at both levels by @mikebronner in #649
  • πŸ› Regressions from 13.1.8 and 13.1.11 (newBaseQueryBuilder trait collision, model() relation lazy-loaded on write) by @danielperez9430 in #640
  • πŸ› Resolve every #650 review point on the #640 builder and cooldown fixes by @mikebronner in #651
  • πŸ› Tag eager-loaded many-to-many queries with their pivot table by @danielperez9430 in #641
  • πŸ› Keep the 13.1.11 tag order and rebuild the pivot tag tests by @mikebronner in #653
  • πŸ›Flush the pivot table tags on a pivot write by @mikebronner in #655
  • πŸ›README: the "What Does Not Get Cached" list is wrong about lazy loads and select() by @mikebronner in #654
  • πŸ›Closure arguments to macros and custom builder methods share one cache key by @mikebronner in #656

New Contributors

Full Changelog: 13.1.11...13.2.0

Don't miss a new laravel-model-caching release

NewReleases is sending notifications on new releases.