Cache Eloquent Relationship query
Here is my approach:
public function bookmarks(): HasMany{ return $this->hasMany(Bookmark::class);}protected function getBookmarksCacheKey(): string{ return sprintf('user-%d-bookmarks', $this->id);}public function clearBookmarksCache(): bool{ return Cache::forget($this->getBookmarksCacheKey());}public function getBookmarksAttribute(): Collection{ if ($this->relationLoaded('bookmarks')) { return $this->getRelationValue('bookmarks'); } $bookmarks = Cache::rememberForever($this->getBookmarksCacheKey(), function () { return $this->getRelationValue('bookmarks'); }); $this->setRelation('bookmarks', $bookmarks); return $bookmarks;}
You can't store a relationship in the cache. You need to cache the actual data retrieved from the database. So you'll have something like this:
public function roles(){ return \Cache::remember('user_' . $this->id . '_roles', 10, function() { return $this->hasMany('App\Role')->get()->toArray(); });}
And now you have to access it as a method, not a property, because it's not returning a relation anymore (and Eloquent would throw an exception):
$user->roles();
Now you should get an array as you want.
If you want to cache user together with its roles you can do it this way:
$user = User::find(1);$user->load('roles');Cache::put('users_'.$user->id, $user, 10);
I don't know why, but you need to use load
here instead of with
. If you used with
you would get error that you cannot cache PDO
instance.