I have a model called Area
which contains a list of area names that I need to populate a dropdown. The list is translated using the Rainlab Translate plugin.
If I just do a straightforward Area::lists()
then the list is not translated. However, if I do Area::get()->lists()
then it is translated but one query is run on the rainlab_translate_attributes
table for every single item in the dropdown, causing ~100 queries to run and a 1.5s request duration.
Model
<?php namespace Namespace\PluginName\Models;
use Model;
class Area extends Model
{
public $implement = ['RainLab.Translate.Behaviors.TranslatableModel'];
public $translatable = ['name'];
// ....
}
View
<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>
Component Option #1 (fast query but items don't get translated)
public function areas() {
return Area::lists('name','id');
}
Component Option #2 (items translated but ~100 queries and very slow)
public function areas() {
return Area::get()->lists('name','id');
}
In other similar situations I would add public $with = ['relation']
but the rainlab_translate_attributes
table doesn't seem to have a model that I could related the Area
model to.
UPDATE
I have created the following functions in my Area.php
model:
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 );
}
...and then in my component, I have tried:
$areas = Area::listAreas();
<-- this reads cached data immedately
$areas->lists('name','id');
<-- this causes a new query to be generated for every item in the collection, here's an example of one query:
select * from
rainlab_translate_attributeswhere
locale= 'th' and
model_id= '1275' and
model_type= 'Namespace\PluginName\Models\Area' limit 1
I have verified that App::getLocale()
is correctly set as th