關於yii2 ActiveDataProvider 遇到 hasMany 和多對多關係時的處理技巧

開頭日常吐槽yii的文檔

其實我們都知道使用provider進行分頁和排序。eg:


$query = User::find()->where(['status'=>1');

$provider = new ActiveDataProvider([
    'query' => $query,
    'pagination' => [
        'pageSize' => 10,
    ],
    'sort' => [
        'defaultOrder' => [
            'register_time' => SORT_ASC,
        ],  
    ],
]);

return $this->render('user', ['provider' => $provider]);

HTML


<?php
use yii\grid\GridView;

?>

<?= GridView::widget([
    'dataProvider' => $provider,
]) ?>

hasMany遇到的問題

當我們需要關聯表的時候joinWith,hasOne不會出現問題,當出現hasMany時,你會發現你得到的每頁項目數並不是你定好的10個每頁,而可能是5?4?等等。。。

  • User.php

//假設一個用戶可以開多家店
public function getStores()
{
    return $this->hasMany(Store::className(), ['id' => 'store_id']);
}
  • IndexController

public function actionUser()
{
    $query = User::find()->joinWith('stores')->where(['status' => 1]);

    //其他同上
    //...

    echo $provider->getTotalCount();
    echo $provider->getCount();    
}

如果你原來有100個用戶,正常的數據獲取的total count應該也是100,但是你會發現並不是,可能是200,300.

獲取的count每頁應該是10個,但是你得到的可能是5個,4個。

原因:

百度查詢真的查不到東西,都是很初級的provider怎麼使用,只能翻牆去查google,在github中找到了老外的提問,發現開發者回答了他,如果是一對多的話,獲取到的數據可能會有重複,並且給出瞭解決辦法:加->distinct() 去重

即:


$query = User::find()->joinWith('stores')->where(['status' => 1])->distinct();

多對多如何重複關聯一張表

比如user表裏有兩個字段,分別對應了他開的兩個店的id,此時想要關聯store表將兩個店名都顯示,該如何做

實際開發中其實應該有中間表的,假如真的有這種情況,該如何查詢

解決辦法

給表起別名來避免關聯表名重複


//User.php

function getStores()
{
    return $this->hasOne(Store::className(), ['id' => 'store_id'])->from(Store::tableName().' alias_store1');
}

我開發中實際碰到問題是,我的user表裏有type和status,我使用的是字典表:

dictionary_type:
‘id’ — 類型id
‘name’ — 類型名稱

dictionary_data:
‘id’ — user表中的type、status的值
‘name’ — 對應的名稱
‘type’ — 對應dic_type表中的id

所以我需要關聯表查出type和status都對應的什麼含義,顯示在頁面上,所以就需要分別關聯兩次dictionary_data表

————- 爬坑不易,且爬且珍惜 —————————–

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章