@morawcik The remember() Cache method works a little differently than how you're trying to use it. It will first try to retrieve an item, by its key, out of the cache if it already exists, otherwise it will run the closure and store the results into cache. So, you most likely already set the products key in cache with the full results when you were experimenting, and your updated closure was never being executed. If you call Cache::forget('products'); and then try again, I bet you'll get the result you're after. Also, using Cache::put() will replace the item in the cache.
Limit fields for cached paginated models
Hi. I have simple Cache::remember with return Product::paginate(20) Now I want to save to cache all fields but description and i tried with select() and adding column to paginate() (with listed all fields except description) but it always saved with all fields - even with description. I dumped result and in all cases it returns models without description field. I tried even add description to Product $hidden but without changes.
That's my basic version
Cache::remember('products', 3600, function() {
return Product::paginate(20);
});
and with trying to limit to those fields:
Cache::remember('products', 3600, function() {
return Product::select(['id', 'name', 'created_at'])->paginate(20);
});
or
Cache::remember('products', 3600, function() {
return Product::paginate(20, ['id', 'name', 'created_at']);
});
@Talinon I cleared cache so many times that I can't even count that ;)
@morawcik Do you have $appends declared in your Product model?
@Talinon Nope - it's just a clean model. The only thing what i used here during "tests" was $hidden
@morawcik So to recap, when you do this:
dd(Product::select(['id', 'name', 'created_at'])->paginate(20));
There is NO description field? But once you cache it, the description field magically appears when you get the key out of Cache?
I still say there must be some problem with clearing your cache. What cache driver are you using?
Try running php artisan tinker and try these commands:
\Cache::forget('products');
\Cache::get('products'); // should return null.. if it doesn't, then there is certainly a problem
$products = Product::select(['id', 'name', 'created_at'])->paginate(20);
\Cache::put('products', $products);
\Cache::get('products')->all(); // should have all products with only id, name, created_at fields
Again, if get() doesn't return null after calling forget(), then there must be something wrong with your cache driver or configuration. If you're using the file cache driver, make sure you've set up the file permissions properly on the storage/framework/cache directory. Maybe the framework can't delete the files.
@Talinon Yes, there is no description. I'm using file driver. Permissions are ok - it deletes all files in cache folder (also tested with manual removing) I'll check tinker "demo" later in home.
did you run php artisan cache:clear ? make sure to run this so it will clear the cache whenever you modify your code ; or you can add Cache::forget('products') before calling your function
@sevenTopo Yes, I did it a lot trying to get it work
if you remove the cache:remember from your script , does this part of code gives u the result u want ?
return Product::paginate(20, ['id', 'name', 'created_at']);
//or this return Product::select(['id', 'name', 'created_at'])->paginate(20);
@sevenTopo Without/outside of cache it returns without description
@morawcik so you say that your code work's as expected if you don't use cache but if you use cache you got the wrong answears ;
and you are sure that you clear all cache including the keys 'products-'.$currentPage ? can you please add an return statement before Cache::remember and change the keys make productsxxx- for example and parse the results of it
return Cache::remember('products-' . $currentPage, 3600, function() {
return Product::paginate(20, ['id', 'name', 'created_at']);
});
i don't understand how you can cache paginated results
how do you use the cached data?
@Snapey It's just a simplest demo I can test for this. In real example i have sth like this
Cache::remember('products-' . $currentPage, 3600, function() {
return Product::paginate(20, ['id', 'name', 'created_at']);
});
@morawcik but that does not show how you use the cached data. Perhaps you don't understand the function of remember.
$products = Cache::remember('products-' . $currentPage, 3600, function() {
return Product::paginate(20, ['id', 'name', 'created_at']);
});
which then returns the cache or refetches the data, putting it into the cache.
The result set will be limited to page 1, which makes pagination pointless, it would be quicker to just use limit(20)
@Snapey With my example for each page there is a different key for cache ('products-1', 'products-2' etc) so where is the problem?
@morawcik where is the problem? You only half explain the problem.
in your "simplest demo I can test" you don't actually use the cached data
@Snapey Sorry but I don't get it - for me it's no matter how I'm using this data because the problem is to retrieve the "correct" data (from cache). So if i use it later in view, send with api or save to excel I'll still have the same $products content from cache.
[Edit] Oh, it was kinda confusing because my first reply to you should be for this https://laracasts.com/discuss/channels/general-discussion/limit-fields-for-cached-paginated-models?reply=909377 reply
If it comes about using this cache data - i'm just using it in my view (simple foreach to listing products data)
@morawcik because if you don't go via the cached results, you will just load fresh data.
So, asking again HOW are you using the cached results.
@Snapey I don't know if you saw edited replay but I'm using it in view just in foreach loop
view('products.index', ['products' => $products]);
Sorry but I don't understand first part - remember doesn't work like this:
- try to get data for this key
- if cache is empty or expired then save to this cache data from closure (in this case paginated products) and return it (to the
$productsvariable) right? So now you are saying that if i don't you$productsanywhere then each time I run thisCache::rememberit's a fresh data (always running closure no matter if cache is not cleared or expired) ?
@morawcik ok, so a bit of info
view('products.index', ['products' => $products]);
but where does $products get set?
All your examples just cache the data, not get the data from cache.
and return it (to the $products variable) right?
but you don't show that anywhere
@Snapey Maybe it's not obvious but it's in the first message - i didn't show $products variable but it's the same:
// example with trying to hide/skip description
$products = Cache::remember('products', 3600, function() {
return Product::select(['id', 'name', 'created_at'])->paginate(20);
});
@morawcik We are trying to help you with code that should, on the face of it, work, but you leave out details or introduce ambiguity by editing down your question to something which you think is all we need to help.
So, your FULL code might be like
$products = Cache::remember('products-' . $currentPage, 3600, function() {
return Product::select(['id', 'name', 'created_at'])->paginate(20);
});
return view('products.index', ['products' => $products]);
and then in the view you are looping over products like
@foreach($products as $product)
and nothing else strange?
@Snapey Yes, it's all.
I didn't put more code because I don't know how view or passing data to view can affect to what I'm getting from cache
@morawcik because you might not be actually using the instance you got from cache.
So then maybe the issue is with how you are determining there is a problem?
@Snapey There is no way for other instance. That's the whole method
public function index()
{
$products = Cache::remember('products-' . $currentPage, 3600, function() {
return Product::select(['id', 'name', 'created_at'])->paginate(20);
});
//dd($products);
return view('products.index', ['products' => $products]);
and the view which i'm using right now
@foreach($products as $product)
<div>
{{ $product->id }} <br>
{{ $product->description }}
</div>
@endforeach
and even with this dd() above i see description
@morawcik I can't see anything wrong with the code, and my mock up of the same performs exactly as expected.
And you have NOTHING extra in the model?
@Snapey Nothing
Please or to participate in this conversation.