How would you forget cached Eloquent models in Laravel?
Solution 1
So i was looking for an answer to the same question as OP but was not really satisfied with the solutions. So i started playing around with this recently and going through the source code of the framework, I found out that the remember()
method accepts second param called key
and for some reason it has not been documented on their site (Or did i miss that?).
Now good thing about this is that, The database builder uses the same cache driver which is configured under app/config/cache.php
Or should i say the same cache system that has been documented here - Cache. So if you pass min and key to remember()
, you can use the same key to clear the cache using Cache::forget()
method and in fact, you can pretty much use all the Cache
methods listed on the official site, like Cache::get()
, Cache::add()
, Cache::put()
, etc. But i don't recommend you to use those other methods unless you know what you're doing.
Here's an example for you and others to understand what i mean.
Article::with('comments')->remember(5, 'article_comments')->get();
Now the above query result will be cached and will be associated with the article_comments
key which can then be used to clear it anytime (In my case, I do it when i update).
So now if i want to clear that cache regardless of how much time it remembers for. I can just do it by calling Cache::forget('article_comments');
and it should work just as expected.
Hope this helps everyone :)
Solution 2
I think a good way to do is like this:
$value = Cache::remember('users', $minutes, function()
{
return DB::table('users')->get();
});
and then use Model Observers to detect the event of updating the model
class UserObserver {
public function saving($model)
{
//
}
public function saved($model)
{
// forget from cache
Cache::forget('users');
}
}
User::observe(new UserObserver);
Peter Fox
Updated on July 16, 2022Comments
-
Peter Fox almost 2 years
Theoretical question on Laravel here.
So Example of the caching I'd do is:
Article::with('comments')->remember(5)->get();
Ideally I'd like to have an event for Article updates that when the ID of a instance of that model (that's already cached) is updated I want to forget that key (even if it's the whole result of the query that's forgotten instead of just that one model instance), it is possible to do so?
If not is there some way to implement this reasonably cleanly?
-
Peter Fox over 10 yearsWhen I run DB::table('users')->get(); this won't get instances of a Eloquent model will it, it'll only get the results of the query as an array of generic objects? Thought I assume I can return the result of the Eloquent model query rather than a direct DB query right?
-
Glad To Help over 10 yearsI believe you should use
User::whereSomething('something')->get()
if you want to cache the Eloquent collection of objects and if you want to just store the properties to convert it to an array like:User::whereSomething('something')->get()->toArray()
. -
Peter Fox over 10 yearsIn the getCached method, where does the $key variable get initiated?
-
tharumax over 10 yearsIt is retrieved in
getCacheInfo()
function and the key is generated ingenerateCacheKey()
function inIlluminate/Database/Query/Builder.php
. Apparently you can set your own key by using inremember()
method according to the API. However it seems to be neglected in thegetCacheKey()
function. -
tharumax over 10 yearsThe method I mentioned above works pretty well for the simple queries and most of the relationships. However when pivot table is present (in many to many relationships it does not work as expected.
-
Makita over 10 yearsGood answer, thank you. For those who are unclear, the first argument to remember is the number of minutes to cache. laravel.com/api/…
-
Alias over 9 yearsLate to the party, but this doesn't work for me. Doesn't return any data.
-
Syed I.R. over 9 years@Alias what version of Laravel you used? It should work fine unless they made some changes in recent versions which I'm yet to take a look.
-
Scott C almost 9 yearsIn recent versions, the cache functions are no longer built into the model. One must cache the results from the model explicitly, not as part of the chained functions.