Skip to content

Instantly share code, notes, and snippets.

@BrekiTomasson
Last active October 25, 2022 11:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BrekiTomasson/70315b2492a5aaf5a74c5509d6381596 to your computer and use it in GitHub Desktop.
Save BrekiTomasson/70315b2492a5aaf5a74c5509d6381596 to your computer and use it in GitHub Desktop.
Laravel Trait to use in your Model classes to offer a $this->taggedCache() shortcut to your Cache
<?php
declare(strict_types = 1);
namespace App\Concerns\Traits\Models;
use Illuminate\Cache\TaggedCache;
use Illuminate\Support\Facades\Cache;
/**
* Simplify handling of Cache Tags for Laravel Models.
*
* @property string $cacheTagIdentifier Optional tag to use instead of the model name.
*/
trait HasCacheTagsById
{
/**
* @return array<int, string|int>
*/
public function cacheTags(...$extraTags): array
{
return [
$this->getCacheTagsClassName(),
str($this->getCacheTagsClassName())
->singular()
->append(':')
->append($this->getCacheTagsUniqueIdentifier())
->toString(),
...$extraTags,
];
}
public function modelCacheTag(): string
{
return str($this->getCacheTagsClassName())
->append(':')
->append($this->getCacheTagsUniqueIdentifier())
->toString();
}
public function taggedCache(...$extraTags): TaggedCache
{
return Cache::tags($this->cacheTags(...$extraTags));
}
public function getCacheTagsClassName(): string
{
return (new static())->getTable();
}
private function getCacheTagsUniqueIdentifier(): string
{
$identifier = ($this->getAttribute($this->cacheTagIdentifier) ?? $this->getAttribute('id'));
return str($identifier)->snake()->toString();
}
}
@BrekiTomasson
Copy link
Author

BrekiTomasson commented Sep 17, 2022

If you include this file in your project and use HasCacheTagsById; you will be able to do things like:

    public function getDisplayNameAttribute(): string
    {
        return $this->taggedCache()->remember(
            'displayname',
            now()->addHour(),
            fn () => $this->nickname ?? $this->name ?? $this->email
        );
    }

The taggedCache() method will ensure that your displayname cache key is tagged with users and user:4 (assuming the user in question has user ID 4), so that there is no risk of conflict or overlap. You can then use your Event Listeners in order to $user->taggedCache()->flush() whenever a user logs in or whenever specific settings are changed. To flush caches for all users, just Cache::tags('users')->flush().

@BrekiTomasson
Copy link
Author

Note that you can also define the property $cacheTagIdentifier in your model to ensure that the cache tags it generates are distinct enough for that model. If $cacheTagIdentifier is not defined, it uses the name of the database table for the given model by default, using Str::singular() to ensure that your users table can result in a user:4 tag.

@BrekiTomasson
Copy link
Author

This has now been much improved and released as a package which can be found here: https://packagist.org/packages/brekitomasson/laravel-tagged-cache

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment