How would you forget cached Eloquent models in Laravel?

23,831

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);
Share:
23,831
Peter Fox
Author by

Peter Fox

Updated on July 16, 2022

Comments

  • Peter Fox
    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
    Peter Fox over 10 years
    When 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
    Glad To Help over 10 years
    I 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
    Peter Fox over 10 years
    In the getCached method, where does the $key variable get initiated?
  • tharumax
    tharumax over 10 years
    It is retrieved in getCacheInfo() function and the key is generated in generateCacheKey() function in Illuminate/Database/Query/Builder.php. Apparently you can set your own key by using in remember() method according to the API. However it seems to be neglected in the getCacheKey() function.
  • tharumax
    tharumax over 10 years
    The 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
    Makita over 10 years
    Good answer, thank you. For those who are unclear, the first argument to remember is the number of minutes to cache. laravel.com/api/…
  • Alias
    Alias over 9 years
    Late to the party, but this doesn't work for me. Doesn't return any data.
  • Syed I.R.
    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
    Scott C almost 9 years
    In 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.