Reputation: 37
I am trying to cache request for counting number of users in different categories
my function without caching:
public function getNumOfUsersInCat()
{
$numUsers = count($this -> users);
$otherCategories = Category::where('id', '<>', $this -> id) -> get();
foreach($otherCategories as $categ){
if($this -> isAncestorOf($categ))
$numUsers += count($categ -> users);
}
return $numUsers;
}
I was trying to cache requests like:
public function getNumOfUsersInCat()
{
$numUsers = count($this -> users);
$otherCategories = Cache::remember('cache_numuserscat)',60*60*12,function(){
return
Category::where('id', '<>', $this -> id) -> get();
foreach($otherCategories as $categ){
if($this -> isAncestorOf($categ))
$numUsers += count($categ -> users);
}
});
return $numUsers;
}
But I am getting only 0
Laravel 5.7.2
Upvotes: 0
Views: 97
Reputation: 1349
It is because you have put the calculation loop inside your cache and before reaching that part, you return with the category list. So the code you run is actually this:
public function getNumOfUsersInCat()
{
$numUsers = count($this -> users);
$otherCategories = Cache::remember('cache_numuserscat)', 60*60*12, function(){
return Category::where('id', '<>', $this -> id) -> get();
});
return $numUsers;
}
Before the correct code, there are a few things you should note:
$this->id
to the name.withCount
to get the count of all model users in a single query. Your approach have N+1 problem.The Final code can be like this:
public function getNumOfUsersInCat()
{
$cacheName = "cache_num_users_cat_" . $this->id;
return Cache::remember($cacheName, 60 * 60 * 12, function() {
$numUsers = count($this->users);
$otherCategories = Category::query()
->where('id', '<>', $this->id)
->withCount('users')
->get();
foreach ($otherCategories as $categ) {
if ($this->isAncestorOf($categ)) {
$numUsers += $categ->users_count;
}
}
return $numUsers;
});
}
Upvotes: 1