laracasts / matryoshka

Russian Doll Caching in Laravel

Home Page:https://laracasts.com/series/russian-doll-caching-in-laravel

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can you support cache key for Collection?

tortuetorche opened this issue · comments

Is it possible to add getCacheKey() to Illuminate\Database\Eloquent\Builder (or maybe Illuminate\Support\Collection)? Like Rails 5 does.

Example (ported from ruby code):

$users = \App\User::where('name', 'LIKE', '%Alberto%');// Or \App\User::where('name', 'LIKE', '%Alberto%')->get();
$users->getCacheKey();
=> "App\User/query-5942b155a43b139f2471b872ac54251f-3-20150714212107656125000"

References:

Yeah, this is definitely on my todo list. Just need to figure out how we'd specifically go about creating the key for an Eloquent collection.

I wonder if we can get away with this being the cache key for any collection:

"collection/App\Model/{{ $collection->count() }}-{{ $collection->max('updated_at') }}"

So basically "collection/model-name/collection-count-max-updated-at-timestamp"

I think that would be enough? If the collection contents change, the cache will bust.

Yep, but what about collection with where clause? We should use a query signature for them, isn't it?
See: https://github.com/rails/rails/blob/29cf0dd/activerecord/lib/active_record/collection_cache_key.rb#L5

I'm not sure what collection.to_sql would look translate to in our case, though. Hmm..

I think we need to get the original Eloquent Builder instance from an Eloquent Collection.

Maybe we should add the Illuminate\Database\Eloquent\Collection::getQuery() method, like this one.

And overrides the Illuminate\Database\Eloquent\Builder::get() method to push the Eloquent Builder instance inside the Eloquent Collection.

Then we can do things like this:

$collection = \App\User::where('name', 'LIKE', '%Alberto%')->get();

// Inside a `Illuminate\Database\Eloquent\Collection::getCacheKey()` method:
// Get the original Eloquent Builder instance
$collectionQuery = $collection->getQuery();

// And we can access to the Eloquent Builder methods
$collectionQuery->toSql();
$collectionQuery->getBindings();

So this stuff will be really useful to get a query signature for caching purpose...

👍 I didn't test it yet but thank you for adding this feature!