У меня есть модель под названием Area
, которая содержит список имен областей, которые мне нужны для заполнения раскрывающегося списка. Список переводится с помощью плагина Rainlab Translate.
Если я просто сделаю прямое Area::lists()
, то список не будет переведен. Однако, если я делаю Area::get()->lists()
, то он переводится, но выполняется один запрос в таблице rainlab_translate_attributes
для каждого отдельного элемента в раскрывающемся списке, что приводит к выполнению ~ 100 запросов и продолжительности запроса 1,5 с.
Модель
<?php namespace Namespace\PluginName\Models;
use Model;
class Area extends Model
{
public $implement = ['RainLab.Translate.Behaviors.TranslatableModel'];
public $translatable = ['name'];
// ....
}
Просмотреть
<div class="form-group {{ errors.first('location_id') ? 'has-error' }}">
{{ form_label('area_id','Area') }}
{{ form_select('area_id', {'': 'Select...'} + area, null, {'class': 'form-control', 'placeholder': 'Select...'}) }}
<small class="text-danger" data-validate-for="area_id"></small>
</div>
Вариант компонента 1 (быстрый запрос, но элементы не переводятся)
public function areas() {
return Area::lists('name','id');
}
Вариант компонента 2 (элементы переведены, но ~100 запросов и очень медленно)
public function areas() {
return Area::get()->lists('name','id');
}
В других подобных ситуациях я бы добавил public $with = ['relation']
, но в таблице rainlab_translate_attributes
, похоже, нет модели, с которой я мог бы связать модель Area
.
ОБНОВЛЕНИЕ
Я создал следующие функции в моей модели Area.php
:
public static function listAreas()
{
$areas = Cache::rememberForever("all:" . App::getLocale() , function() {
return self::
whereNotNull('iso3166_2')
->get()
->toArray();
});
return self::makeCollection( $areas ) ;
}
public static function makeCollection ( array $models = [] )
{
return self::hydrate( $models );
}
... а затем в моем компоненте я пробовал:
$areas = Area::listAreas();
‹-- это немедленно читает кэшированные данные
$areas->lists('name','id');
‹-- это приводит к созданию нового запроса для каждого элемента в коллекции, вот пример одного запроса:
select * from
rainlab_translate_attributeswhere
locale= 'th' and
model_id= '1275' and
model_type= 'Namespace\PluginName\Models\Area' limit 1
Я убедился, что App::getLocale()
правильно установлено как th
translations
.protected $with = ['translations'];
- person Natwar Singh   schedule 17.03.2021