Answer the question
In order to leave comments, you need to log in
How to reduce number of yii2 requests on GridView?
Hello. Faced a problem. There are tables
1) id, name, subname
2) id, user_id, status, message
It is necessary to provide output of custom columns when displaying table 1 in gridview. Each of which will count the number of records in table 2 with different statuses. (1 custom column - status 1, 2 custom column - status 2)
Now I use the relationship every time when fetching the number of records with a certain status. As a result, +1 request to the database for each column.
Question: How can I execute such a query in one go, save it, and use the saved values for subsequent columns?
SQL: select `status`, count(`id`) from `orders` where `user_id`=*ID here in general via relationship* group by `status`
-----
Here is how the
View is implemented now:
<?= GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
[
'header' => 'Активные заказы',
'format' => 'raw',
'value' => function($model) {
return $model->activeCount;
}
],
[
'header' => 'Ожидают модерации',
'format' => 'raw',
'value' => function($model) {
return $model->moderateCount;
}
],
['class' => 'yii\grid\ActionColumn']
],
]); ?>
class Users extends ActiveRecord
{
public static function tableName()
{
return 'users';
}
public function rules()
{
/*----*/
}
public function attributeLabels()
{
/*----*/
}
public function getOrders()
{
return $this->hasMany(Orders::className(), ['user_id' => 'id']);
}
public function getActiveCount()
{
return $this->getCount(1);
}
public function getModerateCount()
{
return $this->getCount(0);
}
private function getCount($status)
{
return $this->getOrders()->where(['status' => $status])->count();
}
}
Answer the question
In order to leave comments, you need to log in
Decision:
public function getOrdersAggregation()
{
return $this->getOrders()
->select(['status', 'count' => 'count(*)'])
->groupBy('status')
->asArray(true);
}
public function getOrdersStatusCount(int $status) : int
{
if( empty($this->ordersAggregation) ) {
return 0;
}
$result = ArrayHelper::map($this->ordersAggregation, 'status', 'count');
if( ! array_key_exists($status, $result) ) {
return 0;
}
return $result[ $status ];
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question