AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
翻译准备中
Cache helpers for Laravel Eloquent models
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
Attach arbitrary cached values to Eloquent model instances or classes using any Laravel cache driver. By default each authenticated user gets an isolated cache namespace, so two users never share the same cached value for the same model.
See the full documentation (or browse docs/ directly): Installation, Usage, Facade, Customization.
1. Add the trait to your model
That is all the setup required. Every public method below becomes available on the model.
These methods are scoped to a specific model record (e.g. Video with id = 5).查看完整 README ↗Attach arbitrary cached values to Eloquent model instances or classes using any Laravel cache driver. By default each authenticated user gets an isolated cache namespace, so two users never share the same cached value for the same model.
See the full documentation (or browse docs/ directly): Installation, Usage, Facade, Customization.
Install the package via Composer:
composer require foxws/laravel-modelcache
Optionally publish the config file:
php artisan vendor:publish --tag="modelcache-config"
| Variable | Default | Description |
|---|---|---|
MODEL_CACHE_ENABLED | true | Toggle caching on/off globally |
MODEL_CACHE_STORE | CACHE_STORE | Cache store to use (any store from config/cache.php) |
MODEL_CACHE_LIFETIME | 604800 (1 week) | Default TTL in seconds |
[!TIP] Let your AI agent do the hard parts. This package ships a Laravel Boost skill,
modelcache-development, that teaches your agent how to install, configure and use Laravel Model Cache. Install Boost and select the skill when prompted:composer require laravel/boost --dev php artisan boost:installAlready using Boost? Run
php artisan boost:update --discoverto pick up the skill. Then just ask, for example: "Remember each user's playback position on my Video model."
use Foxws\ModelCache\Concerns\InteractsWithModelCache;
use Illuminate\Database\Eloquent\Model;
class Video extends Model
{
use InteractsWithModelCache;
}
That is all the setup required. Every public method below becomes available on the model.
These methods are scoped to a specific model record (e.g. Video with id = 5).
Store a value:
$video = Video::findOrFail(5);
$video->modelCache('playback_position', 142);
// With a custom TTL
$video->modelCache('random_seed', 0.73, now()->addHours(6));
$video->modelCache('last_viewed', now(), 3600); // TTL as seconds
Retrieve a value:
$position = $video->modelCached('playback_position'); // null if not cached
$seed = $video->modelCached('random_seed', 0.5); // 0.5 as fallback
Check existence:
if (! $video->modelCacheHas('playback_position')) {
$video->modelCache('playback_position', 0);
}
Forget a value:
$video->modelCacheForget('playback_position');
Remember a value (fetch or store):
modelCacheRemember returns the cached value if it exists, otherwise resolves the closure (or uses the plain value), stores it, and returns it.
// With a closure (recommended for expensive operations)
$stats = $video->modelCacheRemember('stats', fn() => $this->computeExpensiveStats($video), now()->addDay());
// With a plain value
$video->modelCacheRemember('random_seed', 0.73, now()->addHours(6));
Practical example — lazy-load an expensive computed value:
class VideoController extends Controller
{
public function show(Video $video): JsonResponse
{
$stats = $video->modelCacheRemember('stats', fn() => $this->computeExpensiveStats($video), now()->addDay());
return response()->json($stats);
}
}
These static methods are scoped to the model class rather than a specific record. Useful for values shared across all instances, such as global seeds or configuration.
Store a value:
Video::setModelCache('random_seed', 0.42);
Video::setModelCache('random_seed', 0.42, now()->addWeek());
Retrieve a value:
$seed = Video::getModelCache('random_seed'); // null if not cached
$seed = Video::getModelCache('random_seed', 0.5); // with fallback
Check existence:
if (! Video::hasModelCache('random_seed')) {
Video::setModelCache('random_seed', rand() / getrandmax());
}
Forget a value:
Video::forgetModelCache('random_seed');
Use the ModelCache facade when you need to interact with caching outside of a model — for example in an action class or a service.
use Foxws\ModelCache\Facades\ModelCache;
class RecordPlaybackPosition
{
public function handle(Video $video, int $seconds): void
{
if (! ModelCache::enabled()) {
return;
}
if (! ModelCache::shouldCache($video, 'playback_position', $seconds)) {
return;
}
ModelCache::cache($video, 'playback_position', $seconds, now()->addDay());
}
}
// Read from cache
$position = ModelCache::getCachedValue($video, 'playback_position');
// Check
$exists = ModelCache::hasBeenCached($video, 'playback_position');
// Forget one or multiple keys
ModelCache::forget($video, 'playback_position');
ModelCache::forget($video, ['playback_position', 'random_seed']);
shouldModelCache)Override shouldModelCache on the model to conditionally skip caching certain keys or values:
class Video extends Model
{
use InteractsWithModelCache;
public function shouldModelCache(string $key, mixed $value = null): bool
{
// Never cache a null value
if ($value === null) {
return false;
}
// Only cache specific keys
if (! in_array($key, ['playback_position', 'random_seed', 'stats'])) {
return false;
}
return true;
}
}
A cache profile controls global caching behaviour: whether caching is enabled, when values expire, and which per-user namespace suffix to use. The default is CacheAllSuccessful, which caches all values for all users.
Create your own by implementing CacheProfile:
use Foxws\ModelCache\CacheProfiles\BaseCacheProfile;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
class AuthenticatedUserCacheProfile extends BaseCacheProfile
{
public function shouldUseCache(Model $model, string $key): bool
{
// Only cache for authenticated users
return Auth::check();
}
public function shouldCacheValue(mixed $value = null): bool
{
// Do not cache null or empty strings
return $value !== null && $value !== '';
}
}
Register it in config/modelcache.php:
'cache_profile' => AuthenticatedUserCacheProfile::class,
cacheNameSuffix)By default, BaseCacheProfile::useCacheNameSuffix returns the authenticated user's ID, isolating each user's cache. You can override this per model:
class Video extends Model
{
use InteractsWithModelCache;
protected function cacheNameSuffix(string $key): string
{
// Shared cache regardless of who is logged in
return '';
}
}
class Post extends Model
{
use InteractsWithModelCache;
protected function cacheNameSuffix(string $key): string
{
// Separate cache per user
return Auth::check() ? (string) Auth::id() : '';
}
}
class Report extends Model
{
use InteractsWithModelCache;
protected function cacheNameSuffix(string $key): string
{
// Separate cache per key type, shared across users
return $key;
}
}
composer test
Please see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details.
Please review our security policy on how to report security vulnerabilities.
This package is heavily inspired by and based on the spatie/laravel-responsecache package by Spatie.
If you find their work valuable, please consider sponsoring Spatie or purchasing one of their courses and products.
The MIT License (MIT). Please see License File for more information.