Как оптимизировать контроллер на Yii2?

Доброго времени суток! В проекте некоторые действия контроллеров содержат очень много выборок из бд, например
/** @var Question|null $question */
$question = Question::findOne([
    'url' => $slug,
    'deleted' => 0,
    'moderated' => 0
]);

$id = $question->id;

/** @var Question $question Вопрос */
$question = Question::find()
    ->with('screenshot')
    ->select([
        Question::tableName() . '.*',
        'SUM(views) as totalViews'
    ])
    ->joinWith('postView')
    ->with(['category', 'subcat'])
    ->where([Question::tableName() . '.slug' => $slug])
    ->one();

/** @var array $lastQuestions */
$lastQuestions = Question::find()
    ->where([
        'moderated' => 0,
        'deleted' => 0
    ])
    ->andWhere('id != ' . $question->id)
    ->orderBy('published_date DESC')
    ->limit(4)
    ->all();

/** @var array $similarQuestions */
$similarQuestions = Question::find()
    ->where([
        'moderated' => 0,
        'deleted' => 0
    ])
    ->andWhere(['not in', 'id', ArrayHelper::getColumn($lastQuestions, 'id')])
    ->andWhere('id != ' . $question->id)
    ->limit(6)
    ->all();

$countComment = QuestionComment::find()
    ->where([
        'id' => $id,
        'deleted' => 0,
    ])
    ->count();

В документации же советуют облегчать контроллеров. Скажите, как можно оптимизировать такой код контроллеров и вообще какой материал можете посоветовать по лучшим практикам разработки на Yii? Заранее спасибо!
  • Вопрос задан
  • 142 просмотра
Решения вопроса 1
vitaly_74
@vitaly_74
Про материал: https://elisdn.ru/blog/search?q=yii2
или используйте паттерн DTO - и в него запихните все запросы которые вам необходимы в экшене и получится примерно так:
$dto->similarQuestions()
или можно пойти еще дальше и создать Active Query как сделано здесь https://github.com/ElisDN/yii2-demo-catalog/blob/m...
и тогда можно будет сделать так:
$dto->questions()->similar();
$dto->questions()->last();
$dto->questions()->count(); //или тут использовать связь и вызывать count как свойство.
Ну а в будущем если понадобится просто оптимизируете запросы questions или в файле DTO или его составные части уже непосредственно в файле QuestionsSubQuery(или назвать просто QuestionsQuery)
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
rpsv
@rpsv
делай либо хорошо, либо никак
Кусок кода: Question::find(), генерирует ActiveQuery, отнаследуйтесь от стандартного, и реализуйте часто используемые конструкции в нем.

Документация: https://www.yiiframework.com/doc/guide/2.0/ru/db-a...
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы