|
| 1 | +--- |
| 2 | +title: Model Caching for Laravel |
| 3 | +description: Building a navigation menu for your site |
| 4 | +extends: _layouts.docs |
| 5 | +section: content |
| 6 | +repository_url: https://github.com/GeneaLabs/laravel-model-caching |
| 7 | +--- |
1 | 8 | # Model Caching for Laravel
|
2 | 9 | [](https://travis-ci.org/GeneaLabs/laravel-model-caching)
|
3 | 10 | [](https://scrutinizer-ci.com/g/GeneaLabs/laravel-model-caching)
|
4 |
| -<img src='https://bettercodehub.com/edge/badge/GeneaLabs/laravel-model-caching?branch=master'> |
| 11 | + |
5 | 12 | [](https://coveralls.io/github/GeneaLabs/laravel-model-caching)
|
6 | 13 | [](https://github.com/GeneaLabs/laravel-model-caching)
|
7 | 14 | [](https://packagist.org/packages/genealabs/laravel-model-caching)
|
8 | 15 | [](https://raw.githubusercontent.com/GeneaLabs/laravel-model-caching/master/LICENSE)
|
9 | 16 |
|
10 | 17 | 
|
11 | 18 |
|
12 |
| -Documentation has moved to https://genealabs.com/docs/laravel-model-caching/. |
13 |
| - |
14 | 19 | ## Supporting This Package
|
15 | 20 | This is an MIT-licensed open source project with its ongoing development made possible by the support of the community. If you'd like to support this, and our other packages, please consider [becoming a backer or sponsor on Patreon](https://www.patreon.com/mikebronner).
|
16 | 21 |
|
| 22 | +## Impetus |
| 23 | +I created this package in response to a client project that had complex, nested |
| 24 | +forms with many `<select>`'s that resulted in over 700 database queries on one |
| 25 | +page. I needed a package that abstracted the caching process out of the model |
| 26 | +for me, and one that would let me cache custom queries, as well as cache model |
| 27 | +relationships. This package is an attempt to address those requirements. |
| 28 | + |
| 29 | +## Features |
| 30 | +- automatic, self-invalidating relationship (only eager-loading) caching. |
| 31 | +- automatic, self-invalidating model query caching. |
| 32 | +- automatic use of cache tags for cache providers that support them (will |
| 33 | + flush entire cache for providers that don't). |
| 34 | + |
| 35 | +## Requirements |
| 36 | +- PHP >= 7.1.3 |
| 37 | +- Laravel 5.8 |
| 38 | + ```diff |
| 39 | + - Please note that prior Laravel versions are not supported and the package |
| 40 | + - versions that are compatible with prior versions of Laravel contain bugs. |
| 41 | + - Please only use with the versions of Laravel noted above to be compatible. |
| 42 | + ``` |
| 43 | + |
| 44 | +### Possible Conflicting Packages |
| 45 | +Any packages that override `newEloquentModel()` from the `Model` class will |
| 46 | +likely conflict with this package. Of course, any packages that implement their |
| 47 | +own Querybuilder class effectively circumvent this package, rendering them |
| 48 | +incompatible. |
| 49 | + |
| 50 | +The following are packages we have identified as incompatible: |
| 51 | +- [grimzy/laravel-mysql-spatial](https://github.com/grimzy/laravel-mysql-spatial) |
| 52 | +- [fico7489/laravel-pivot](https://github.com/fico7489/laravel-pivot) |
| 53 | +- [chelout/laravel-relationship-events](https://github.com/chelout/laravel-relationship-events) |
| 54 | +- [spatie/laravel-query-builder](https://github.com/spatie/laravel-query-builder) |
| 55 | +- [dwightwatson/rememberable](https://github.com/dwightwatson/rememberable) |
| 56 | + |
| 57 | +### Things That Don't Work Currently |
| 58 | +The following items currently do no work with this package: |
| 59 | +```diff |
| 60 | +- caching of lazy-loaded relationships, see #127. Currently lazy-loaded belongs-to relationships are cached. Caching of other relationships is in the works. |
| 61 | +- using select() clauses in Eloquent queries, see #238 (work-around discussed in the issue) |
| 62 | +``` |
| 63 | + |
| 64 | +[](https://vimeo.com/256318402) |
| 65 | + |
| 66 | +## Installation |
| 67 | +Be sure to not require a specific version of this package when requiring it: |
| 68 | +``` |
| 69 | +composer require genealabs/laravel-model-caching:* |
| 70 | +``` |
| 71 | + |
| 72 | +## Upgrade Notes |
| 73 | +### 0.6.0 |
| 74 | +The environment and config variables for disabling this package have changed. |
| 75 | +- If you have previously published the config file, publish it again, and adjust as necessary: |
| 76 | + ```sh |
| 77 | + php artisan modelCache:publish --config |
| 78 | + ``` |
| 79 | + |
| 80 | +- If you have disabled the package in your .env file, change the entry from `MODEL_CACHE_DISABLED=true` to `MODEL_CACHE_ENABLED=false`. |
| 81 | + |
| 82 | +### 0.5.0 |
| 83 | +The following implementations have changed (see the respective sections below): |
| 84 | +- model-specific cache prefix |
| 85 | + |
| 86 | +## Configuration |
| 87 | +### Recommended (Optional) Custom Cache Store |
| 88 | +If you would like to use a different cache store than the default one used by |
| 89 | +your Laravel application, you may do so by setting the `MODEL_CACHE_STORE` |
| 90 | +environment variable in your `.env` file to the name of a cache store configured |
| 91 | +in `config/cache.php` (you can define any custom cache store based on your |
| 92 | +specific needs there). For example: |
| 93 | +``` |
| 94 | +MODEL_CACHE_STORE=redis2 |
| 95 | +``` |
| 96 | + |
| 97 | +## Usage |
| 98 | +For best performance a taggable cache provider is recommended (redis, |
| 99 | +memcached). While this is optional, using a non-taggable cache provider will |
| 100 | +mean that the entire cache is cleared each time a model is created, saved, |
| 101 | +updated, or deleted. |
| 102 | + |
| 103 | +For ease of maintenance, I would recommend adding a `BaseModel` model that |
| 104 | +uses `Cachable`, from which all your other models are extended. If you |
| 105 | +don't want to do that, simply extend your models directly from `CachedModel`. |
| 106 | + |
| 107 | +Here's an example `BaseModel` class: |
| 108 | + |
| 109 | +```php |
| 110 | +<?php namespace App; |
| 111 | + |
| 112 | +use GeneaLabs\LaravelModelCaching\Traits\Cachable; |
| 113 | + |
| 114 | +abstract class BaseModel |
| 115 | +{ |
| 116 | + use Cachable; |
| 117 | + // |
| 118 | +} |
| 119 | +``` |
| 120 | + |
| 121 | +### Multiple Database Connections |
| 122 | +__Thanks to @dtvmedia for suggestion this feature. This is actually a more robust |
| 123 | +solution than cache-prefixes.__ |
| 124 | + |
| 125 | +Keeping keys separate for multiple database connections is automatically handled. |
| 126 | +This is especially important for multi-tenant applications, and of course any |
| 127 | +application using multiple database connections. |
| 128 | + |
| 129 | +### Optional Cache Key Prefix |
| 130 | +Thanks to @lucian-dragomir for suggesting this feature! You can use cache key |
| 131 | +prefixing to keep cache entries separate for multi-tenant applications. For this |
| 132 | +it is recommended to add the Cachable trait to a base model, then set the cache |
| 133 | +key prefix config value there. |
| 134 | + |
| 135 | +Here's is an example: |
| 136 | +```php |
| 137 | +<?php namespace GeneaLabs\LaravelModelCaching\Tests\Fixtures; |
| 138 | + |
| 139 | +use GeneaLabs\LaravelModelCaching\Traits\Cachable; |
| 140 | +use Illuminate\Database\Eloquent\Model; |
| 141 | +use Illuminate\Database\Eloquent\Relations\BelongsTo; |
| 142 | +use Illuminate\Database\Eloquent\Relations\BelongsToMany; |
| 143 | + |
| 144 | +class BaseModel extends Model |
| 145 | +{ |
| 146 | + use Cachable; |
| 147 | + |
| 148 | + protected $cachePrefix = "test-prefix"; |
| 149 | +} |
| 150 | +``` |
| 151 | + |
| 152 | +The cache prefix can also be set in the configuration to prefix all cached |
| 153 | +models across the board: |
| 154 | +```php |
| 155 | + 'cache-prefix' => 'test-prefix', |
| 156 | +``` |
| 157 | + |
| 158 | +### Exception: User Model |
| 159 | +I would not recommend caching the user model, as it is a special case, since it |
| 160 | +extends `Illuminate\Foundation\Auth\User`. Overriding that would break functionality. |
| 161 | +Not only that, but it probably isn't a good idea to cache the user model anyway, |
| 162 | +since you always want to pull the most up-to-date info on it. |
| 163 | + |
| 164 | +### Experimental: Cache Cool-down In Specific Models |
| 165 | +In some instances, you may want to add a cache invalidation cool-down period. |
| 166 | +For example you might have a busy site where comments are submitted at a high |
| 167 | +rate, and you don't want every comment submission to invalidate the cache. While |
| 168 | +I don't necessarily recommend this, you might experiment it's effectiveness. |
| 169 | + |
| 170 | +To use it, it must be enabled in the model (or base model if you want to use it on multiple or all models): |
| 171 | +```php |
| 172 | +class MyModel extends Model |
| 173 | +{ |
| 174 | + use Cachable; |
| 175 | + |
| 176 | + protected $cacheCooldownSeconds = 300; // 5 minutes |
| 177 | + |
| 178 | + // ... |
| 179 | +} |
| 180 | +``` |
| 181 | + |
| 182 | +After that it can be implemented in queries: |
| 183 | +```php |
| 184 | +(new Comment) |
| 185 | + ->withCacheCooldownSeconds(30) // override default cooldown seconds in model |
| 186 | + ->get(); |
| 187 | +``` |
| 188 | + |
| 189 | +or: |
| 190 | +```php |
| 191 | +(new Comment) |
| 192 | + ->withCacheCooldownSeconds() // use default cooldown seconds in model |
| 193 | + ->get(); |
| 194 | +``` |
| 195 | + |
| 196 | +### Disabling Caching of Queries |
| 197 | +There are two methods by which model-caching can be disabled: |
| 198 | +1. Use `->disableCache()` in a query-by-query instance. |
| 199 | +2. Set `MODEL_CACHE_DISABLED=TRUE` in your `.env` file. |
| 200 | +3. If you only need to disable the cache for a block of code, or for non- |
| 201 | + eloquent queries, this is probably the better option: |
| 202 | + ```php |
| 203 | + $result = app("model-cache")->runDisabled(function () { |
| 204 | + return (new MyModel)->get(); // or any other stuff you need to run with model-caching disabled |
| 205 | + }); |
| 206 | + ``` |
| 207 | + |
| 208 | +**Recommendation: use option #1 in all your seeder queries to avoid pulling in |
| 209 | +cached information when reseeding multiple times.** |
| 210 | +You can disable a given query by using `disableCache()` anywhere in the query chain. For example: |
| 211 | +```php |
| 212 | +$results = $myModel->disableCache()->where('field', $value)->get(); |
| 213 | +``` |
| 214 | + |
| 215 | +### Manual Flushing of Specific Model |
| 216 | +You can flush the cache of a specific model using the following artisan command: |
| 217 | +```sh |
| 218 | +php artisan modelCache:clear --model=App\Model |
| 219 | +``` |
| 220 | + |
| 221 | +This comes in handy when manually making updates to the database. You could also |
| 222 | +trigger this after making updates to the database from sources outside your |
| 223 | +Laravel app. |
| 224 | + |
| 225 | +## Summary |
| 226 | +**That's all you need to do. All model queries and relationships are now |
| 227 | +cached!** |
| 228 | + |
| 229 | +In testing this has optimized performance on some pages up to 900%! Most often |
| 230 | +you should see somewhere around 100% performance increase. |
| 231 | + |
| 232 | +## Commitment to Quality |
| 233 | +During package development I try as best as possible to embrace good design and development practices, to help ensure that this package is as good as it can |
| 234 | +be. My checklist for package development includes: |
| 235 | + |
| 236 | +- ✅ Achieve as close to 100% code coverage as possible using unit tests. |
| 237 | +- ✅ Eliminate any issues identified by SensioLabs Insight and Scrutinizer. |
| 238 | +- ✅ Be fully PSR1, PSR2, and PSR4 compliant. |
| 239 | +- ✅ Include comprehensive documentation in README.md. |
| 240 | +- ✅ Provide an up-to-date CHANGELOG.md which adheres to the format outlined |
| 241 | + at <https://keepachangelog.com>. |
| 242 | +- ✅ Have no PHPMD or PHPCS warnings throughout all code. |
| 243 | + |
| 244 | +## Contributing |
| 245 | +Please observe and respect all aspects of the included Code of Conduct <https://github.com/GeneaLabs/laravel-model-caching/blob/master/CODE_OF_CONDUCT.md>. |
| 246 | + |
| 247 | +### Reporting Issues |
| 248 | +When reporting issues, please fill out the included template as completely as |
| 249 | +possible. Incomplete issues may be ignored or closed if there is not enough |
| 250 | +information included to be actionable. |
| 251 | + |
| 252 | +### Submitting Pull Requests |
| 253 | +Please review the Contribution Guidelines <https://github.com/GeneaLabs/laravel-model-caching/blob/master/CONTRIBUTING.md>. |
| 254 | +Only PRs that meet all criterium will be accepted. |
| 255 | + |
17 | 256 | ## If you ❤️ open-source software, give the repos you use a ⭐️.
|
18 | 257 | We have included the awesome `symfony/thanks` composer package as a dev
|
19 | 258 | dependency. Let your OS package maintainers know you appreciate them by starring
|
|
0 commit comments