Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

paginate() doeesn't cache the main record #18

Open
eidng8 opened this issue Apr 29, 2016 · 2 comments
Open

paginate() doeesn't cache the main record #18

eidng8 opened this issue Apr 29, 2016 · 2 comments

Comments

@eidng8
Copy link

eidng8 commented Apr 29, 2016

The setup is phpunit & array cache driver. And I've tapped in to the cache using:

$cache = \Cache::store();

The line below:

$paginator = SomeModel::paginate($perPage)->load('relation');

After that, I've found that there are two entries in the cache: the aggregate & relation. The main model (record) is missed.

While traced a bit, I was led to the line, which traced back to query builder (not eloquent builder) getCountForPagination()

public function getCountForPagination($columns = ['*'])
{
    $this->backupFieldsForCount();

    $this->aggregate = ['function' => 'count', 'columns' => $this->clearSelectAliases($columns)];

    $results = $this->get();    // <<<<<< THIS LINE

    $this->aggregate = null;

    $this->restoreFieldsForCount();

    if (isset($this->groups)) {
        return count($results);
    }

    return isset($results[0]) ? (int) array_change_key_case((array) $results[0])['aggregate'] : 0;
}

Then the subsequent call to forPage()->get() will not hit the cache. Because the $cacheMinutes property was set to null in the closure returned by getCacheCallback(). Which ends up failing the non-null test in get().

public function paginate($perPage = 15, $columns = ['*'], $pageName = 'page', $page = null)
{
    $page = $page ?: Paginator::resolveCurrentPage($pageName);

    $total = $this->getCountForPagination($columns);

    $results = $this->forPage($page, $perPage)->get($columns);   // <<<<<<< THIS WON'T HIT CACHE

    return new LengthAwarePaginator($results, $total, $perPage, $page, [
        'path' => Paginator::resolveCurrentPath(),
        'pageName' => $pageName,
    ]);
}
@dwightwatson
Copy link
Owner

Hey, really sorry for the delay in getting to this one. Good find.

I seem to recall the cache callback being added to prevent a circular loop that popped up in an earlier version of Laravel. I will try and take a look into this soon, but also happy to review any PRs.

@eidng8
Copy link
Author

eidng8 commented May 11, 2016

Actually, in my project, I've change the callback to 1-liner

return function() use ($columns) {return parent::get($columns);}

It works for me. But it seems that this repo is ripped off of tests, I'm not sure if this change affects anything unwanted. So I leave it to your decision, and didn't submit a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants