There is an image model. An image can have many ratings from users.

public function getGalleryRatings() { return $this->hasMany(GalleryRating::className(), ['image_id' => 'id']); } 

The average rating of the picture I get

 public function getAverageRating() { $avRating = 0; if (!empty($this->galleryRatings)) { foreach ($this->galleryRatings as $rating) { $avRating += $rating->value; } $avRating = round($avRating / count($this->galleryRatings), 2); } return $avRating; } 

and further I use this getter when printing the grid as one of the columns

 <?= GridView::widget([ ... 'columns' => [ ... 'averageRating', 

Question. How to implement sorting in gridview by this column? I understand that you probably need to prescribe something in GalleryImageSearch and somehow use GROUP BY , but I don’t know how. It would also be interesting to know about filtering by such a column.

1 answer 1

Option 1 (preferred): And what prevents you from adding an averageRating field to the image table and setting it in the GalleryRating::beforeSave() method, GalleryRating::beforeDelete() .

The rating is set once, and the rating will be displayed ten times more.

Option 2:

 class Image extends ActiveRecord { public $averageRating; } Image::find() ->select([ Image::tableName() . '.*', 'averageRating' => 'AVG(' . GalleryRating::tableName() . '.value)' ]) ->joinWith('galleryRatings', false) ->groupBy([Image::tableName() . '.id']) // ... ->all()