π₯ 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()andwhereNot()queries on models with global scopes (#647). morphToeager loads onto models with global scopes (#647).withoutGlobalScopesExcept()calls that keep every scope (#647).- Eager-load constraints that do more than add
whereclauses (#647). - belongsToMany and morphToMany queries onto scoped models, or that use
withPivot(),withTimestamps(), a customas(),using(),with(), or a related model with$with(#647). fromSub(), union andbeforeQuery()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,falseand""used to share a key, as did1and"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()orhaving()value that cannot be keyed reliably, such as an objectserialize()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 arrayjson_encodecannot encode (#656).
β¬οΈ Upgrade steps
- Run
php artisan modelCache:clearafter 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. - Check your models for an untyped
$isCachableand for trait rules that namenewBaseQueryBuilder(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
- @danielperez9430 made their first contribution in #640
Full Changelog: 13.1.11...13.2.0