在 Yii2 中对计算字段进行排序(网格视图)

Sorting calculated fields in Yii2 (Grid View)

我需要对 GridView 中的某些字段 (asc,desc) 进行排序,但计算的是相同的字段。看下面的代码: 搜索模型:

class ObjectSearch extends Object {
use SearchModelTrait;

public function rules()
{
    return [
        ['id', 'integer', 'min' => 1],
    ];
}

public function search($params)
{
    $this->company_id = \Yii::$app->user->identity->companyId;
    $query = Object::find()->where(['company_id' => $this->company_id]);
    $dataProvider = new ActiveDataProvider([
        'query' => $query,
        'pagination' => false,
    ]);
    $dataProvider->setSort([
        'attributes' => [
            'id',
            'name',
            'lastReportResult' => [
                'asc' => ['lastReportResult' =>SORT_ASC ],
                'desc' => ['lastReportResult' => SORT_DESC],
                'default' => SORT_ASC
            ],
            'reportPercentDiff'
        ]
    ]);

    if (!($this->load($params,'ObjectSearch') && $this->validate())) {
        return $dataProvider;
    }

    $this->addCondition($query, 'id');

    return $dataProvider;
}

对象模型中的方法:

public function getLastReportResult()
{
    $lastReport = $this->getLastReport();
    $message = 0;

    if (!empty($lastReport)) {
        $statistic = new ReportStatistic($lastReport);
        $message = $statistic->getPercent();
    }

    return $message;
}

/**
 * @return int
 */
public function getReportPercentDiff()
{
    $lastReport = $this->getLastReport();
    $message = 0;

    if (!empty($lastReport)) {
        $statistic = $lastReport->getReportDiff();

        if (!empty($statistic['diff'])) {
            $message = $statistic['diff']['right_answers_percent_diff'];
        } elseif (!empty($statistic['message'])) {
            $message = $statistic['message'];
        }
    }
    return $message;
}

所以,通过这种方法,我正在计算两个需要排序的字段的值。这种方式不起作用,我有一个数据库异常,因为对象 table 没有这个字段。 exception 如何对这些字段进行排序?

更新:我是这个答案的作者,这个答案不准确。首选方法是使用 database view

将两个 public 属性添加到 ObjectSearch.php 并将其标记为 safe

class ObjectSearch extends Object {
    use SearchModelTrait;
    public $lastReportResult, $reportPercentDiff;
    public function rules()
    {
        return [
            ['id', 'integer', 'min' => 1],
            [['lastReportResult', 'reportPercentDiff'], 'safe']
        ];
    }

    public function search($params)
    {
        $this->company_id = \Yii::$app->user->identity->companyId;
        $query = Object::find()->where(['company_id' => $this->company_id]);
        $dataProvider = new ActiveDataProvider([
            'query' => $query,
            'pagination' => false,
        ]);
        $dataProvider->setSort([
            'attributes' => [
                'id',
                'name',
                'lastReportResult' => [
                    'asc' => ['lastReportResult' =>SORT_ASC ],
                    'desc' => ['lastReportResult' => SORT_DESC],
                    'default' => SORT_ASC
                ],
                'reportPercentDiff' => [
                    'asc' => ['reportPercentDiff' =>SORT_ASC ],
                    'desc' => ['reportPercentDiff' => SORT_DESC],
                    'default' => SORT_ASC
                ],                
            ]
        ]);

        if (!($this->load($params,'ObjectSearch') && $this->validate())) {
            return $dataProvider;
        }

        $this->addCondition($query, 'id');

        return $dataProvider;
}

然后在index.php(你有网格视图的视图文件)中添加lastReportResultreportPercentDiff到所有属性的数组(所有属性列表ob Object型号)

...
<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        ['class' => 'yii\grid\SerialColumn'],

        
        // your other attribute here
        'lastReportResult',
        'reportPercentDiff',

        ['class' => 'yii\grid\ActionColumn'],
    ],
]); ?>
...

更多信息请访问Kartik's blog at Yii

虽然这是一个旧线程,偶然发现了这个并试图找到其他方法来实现纯计算字段的排序但无济于事......不幸的是这个 post 也不是一个答案...... . 只是我觉得有必要 post 在这里提醒那些仍在寻找解决方案的人,以免在尝试给出的解决方案时挠头但仍然失败。

据我测试,来自文档或引用链接的给定示例仅在数据库模式中有列时才有效(无论是在主 table 还是相关的 table 中) .如果您创建的虚拟 attribute/calculated 字段是基于计算的(例如 table 上 2 列的乘法)

,则它将不起作用

例如: table 购买: | purchase_id | product_id |数量 | table 产品: | product_id | unit_price |

然后,如果我们对模型 'purchase' 使用虚拟属性 'purchase_total',它是数量与 unit_price 的乘积(来自购买和产品的联接 table在 product_id) 上,当您尝试使用目前讨论的方法对它们进行排序时,最终您会遇到一个错误,提示找不到 'purchase_total' 列。