Laravel: Как кэшировать данные, полученные из отношения модели?

Существует модель Country и отношение translations следующим образом

<?php

namespace Modules\User\Entities;

use Astrotomic\Translatable\Translatable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Cache;
use Modules\Core\Traits\Rememberable;
use Modules\User\Entities\Sentinel\User;

class Country extends Model
{
    use Rememberable;
    use Translatable;

    protected $table = 'countries';
    public $translatedAttributes = ['name'];
    protected $fillable = [
        'name',
        'code',
        'weight',
    ];

//    protected $rememberCacheTag = 'countries';

    public function users()
    {
        return $this->hasMany(User::class, 'country_id');
    }

    protected static function booted()
    {
        static::addGlobalScope('lang', function (Builder $builder) {
            $builder->whereHas('translations', function (Builder $q) {
                $q->where('locale', App::getLocale());
            });
        });
    }

    public function translations(): HasMany
    {
        return $this->hasMany($this->getTranslationModelName(), $this->getTranslationRelationKey());
    }
}

Мне нужно кэшировать данные отношения translations. До сих пор я пробовал следующее, взятое из Ссылка

$c = Country::with([
    'translations' => function($q){
        $q->remember(600);
    }
])->remember(600)->find($this->country_id);

и это решение тоже

public function translations(): HasMany
{
    return $this->hasMany($this->getTranslationModelName(), $this->getTranslationRelationKey())->remember(600);
}

Но я получил ошибку

Вызов неопределенного метода Illuminate\Database\Eloquent\Relations\HasMany::remember()

Как я могу кэшировать данные, полученные из отношения?

Отвечает ли это на ваш вопрос? Кэшировать Eloquent Relationship query

geertjanknapen 19.04.2023 09:55

@geertjanknapen Я уже видел это раньше. Не работает

M a m a D 19.04.2023 10:00

Почему бы тогда не кэшировать полный запрос?

geertjanknapen 19.04.2023 10:12

@geertjanknapen Пожалуйста, опубликуйте свое предложение в качестве ответа

M a m a D 19.04.2023 10:28

Я сделал, смотрите сами.

geertjanknapen 19.04.2023 11:45
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
0
5
82
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы должны кэшировать весь запрос, так как простое кэширование отношения не работает. (По крайней мере, из коробки, не уверен, что вы можете «взломать» его)

Итак, используя Laravel Cache, это становится следующим образом;

$countryId = $this->countryId;
return Cache::remember("<your_cache_key>", 600, function() use ($countryId) {
   return Country::with(['translations'])->find($countryId);
});

Если вы используете Redis/Predis (или что-то еще, что поддерживает тегирование кеша), вы даже можете добавить к нему теги кеша;

$countryId = $this->countryId;
return Cache::tags([<array_of_cache_tags>])->remember("<your_cache_key>", 600, function() use ($countryId) {
   return Country::with(['translations'])->find($countryId);
});

В примере <your_cache_key> может быть что-то вроде "country_translations:{$countryId}".

<array_of_cache_tags> может быть что-то вроде ["country", "translations"]

Другие вопросы по теме