Mark Loki
Mark Loki

Reputation: 37

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

Upvotes: 0

Views: 97

Answers (1)

Mohsen Nazari
Mohsen Nazari

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:

  • 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;
    });
}

Upvotes: 1

Related Questions