I'm having trouble getting my queries to cache. Anytime I hit my API I am getting fresh results from the DB instead of the Cached results that im going for. The odd thing is if I look in the file cache I can see the cached results and they are exactly what im expecting, yet when I call the API I get fresh results. Below are some snippets of the relevant files. Where am I going wrong here?
Repository Function my API calls:
public function topMonth()
{
$top = $this->repository->month()->top()->joinUser()->remember(30)->get(['things.id', 'things.votes', 'things.title', 'things.description', 'things.tags', 'things.created_at', 'users.id as user_id','users.username','users.picture as user_picture'])->toArray();
return $top;
}
Model
class Thing extends Eloquent
{
public function scopeTop($query)
{
return $query->orderBy('things.votes', 'desc');
}
public function scopeYear($query)
{
return $query->whereRaw("things.created_at > STR_TO_DATE('" . Carbon::now()->subYear() . "', '%Y-%m-%d %H:%i:%s')");
}
public function scopeMonth($query)
{
return $query->whereRaw("things.created_at > STR_TO_DATE('" . Carbon::now()->subMonth() . "', '%Y-%m-%d %H:%i:%s')");
}
public function scopeWeek($query)
{
return $query->whereRaw("things.created_at > STR_TO_DATE('" . Carbon::now()->subWeek() . "', '%Y-%m-%d %H:%i:%s')");
}
public function scopeDay($query)
{
return $query->whereRaw("things.created_at > STR_TO_DATE('" . Carbon::now()->subDay() . "', '%Y-%m-%d %H:%i:%s')");
}
public function scopeJoinUser($query)
{
return $query->join('users', function($join)
{
$join->on('users.id', '=', 'things.created_by');
});
}
}
You will only be able to cache like that if your sql query stays exactly the same. In this instance, it won't due to your top() query scope.
This is due to the way in which the query builder generates a cache key. It converts the whole query into an sql and serializes it's bindings, as obsered in the Laravel code below:
/**
* Generate the unique cache key for the query.
*
* @return string
*/
public function generateCacheKey()
{
$name = $this->connection->getName();
return md5($name.$this->toSql().serialize($this->bindings));
}
Instead, you will have to manually cache this like so;
if (($top = Cache::get('users.top')) === null)
{
$top = $this->repository->month()->top()->joinUser()->get(['things.id', 'things.votes', 'things.title', 'things.description', 'things.tags', 'things.created_at', 'users.id as user_id','users.username','users.picture as user_picture'])->toArray();
Cache::put('users.top', $top, 30);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With