Существует модель 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()
Как я могу кэшировать данные, полученные из отношения?
@geertjanknapen Я уже видел это раньше. Не работает
Почему бы тогда не кэшировать полный запрос?
@geertjanknapen Пожалуйста, опубликуйте свое предложение в качестве ответа
Я сделал, смотрите сами.
Вы должны кэшировать весь запрос, так как простое кэширование отношения не работает. (По крайней мере, из коробки, не уверен, что вы можете «взломать» его)
Итак, используя 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"]
Отвечает ли это на ваш вопрос? Кэшировать Eloquent Relationship query