Well, you say it's not elegant, but I'm not sure what you're trying to achieve. Do you want to cache every call to the database, which sounds really dangerous to me? Or do you want to cache this specific relationship, which looks fine in my opinion? You might be able to clean this code a bit more, but for the rest, it looks fine and does exactly what you want it to do!
Cache Eloquent Queries - Boot OR Service Provider OR ...
There must be a better way of caching teh model. Let’s assume 5 product families with 5 products in each product family with approx 20 product features for each product i.e. a family will have 5 products and each will have 20 features so a total of 100 features for each family. So the relation will be product_family -> hasMany products -> hasMany features.
Example, family = SEO and products Audit, Local SEO, eCommerce SEO. Mobile SEO, and Voice SEO. I want to cache the family with products and features or each product with features.
The example below works, but doesn't seem elegant.
Other options might include:
- A service provider (ProductsServiceProvider) that caches all requests on boot
- A Model boot trait
- A get attribute mutator
Thoughts?
<?php
namespace App\Products;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
class Product extends Model
{
/**
* Create unique cache key
*
* @param string $slug
* @param array $relations
* @return string
*/
public function cacheKey($slug = "", $relations = [])
{
return sprintf(
"%s-%s-%s",
$this->getTable(),
$slug,
implode("-",$relations)
);
}
/**
* Cache Product of slug
*
* @param $slug
* @param array $relations
* @return mixed
*/
public function getCachedProductOfSlug($slug, $relations = [])
{
return Cache::remember($this->cacheKey($slug, $relations) , 60, function () use($slug, $relations) {
return $this->where('slug',$slug)->with($relations)->first();
});
}
/**
* Product of slug
*
* @param $slug
* @param array $relations
* @return mixed
*/
public function productOfSlug($slug, $relations = [])
{
return $this->getCachedProductOfSlug($slug, $relations);
}
}
@nolros Well that helps for the context, thanks for that.
I think your current approach is perfectly fine. If this works for you, then you're good to go ;)
Please or to participate in this conversation.