Gridview sort question

n Grideview, I need to sort a column that is the result of a method that calculates an average, not a value from a DB column.

On my search model, I’m used to doing my $dataProvider->setSort like so:







 'faq_weight' => [

                'asc' => ['faq.faq_weight' => SORT_ASC],

                'desc' => ['faq.faq_weight' => SORT_DESC],

                'label' => 'Weight'

            ],




Super easy to understand. But now I have a method that returns a result, which is an average of ratings, not a value from a DB column. I added it to my Gridview like so:







['attribute'=>'Rating', 'value' => function($model){

                

                return $model->getFaqRatings($model->id);

                 			

            }],




This works perfectly, so far no problem. But what I don’t know how to do is make it a sortable column in gridview. I tried adding the following to $dataProvider->setSort in my search model:







 'Rating' => [

                'asc' => [$this->getFaqRatings($this->id) => SORT_ASC],

                'desc' => [$this->getFaqRatings($this->id) => SORT_DESC],

                'label' => 'Rating'

            ],






But that doesn’t work because it looks for a column that obviously it will not find.

Is there anyway to make my rating attribute sortable in gridview?

I’d say you can’t use ActiveDataProvider for this purpose because it returns rows in the same order as the underlying SQL query.

You can either use ArrayDataProvider:

http://www.yiiframework.com/doc-2.0/yii-data-arraydataprovider.html


$provider = new ArrayDataProvider([

    'allModels' => $query->from('faq')->all(),

    'sort' => [

        'attributes' => [..., 'faqRatings', ...],

    ],

]);

Or you can extend the ActiveDataProvider and override the prepareModels() method:

You would need to bypass pagination when executing the Query and add sorting that would be executed after retrieving models from DB.

Anyway, if you work with large sets of data you may run into some performance issues (as hinted in the ArrayDataProvider docs).

Thanks @vojtech

The array data provider is not an option at this point. I will look into your other suggestion about extending ActiveDataProvider. I wish there were a simpler solution. It seems to me that this would be a fairly common scenario.