Search code examples
laravelcaching

laravel caching return 0


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


Solution

  • 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:

    • Your cache name should only work for this model you are in, so I added $this->id to the name.
    • You can use 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;
        });
    }