如何连接三个表并在网格视图中获取值

How to join three tables and get value in grid view

我有三个 tables :

  1. contacts 有很多组
  2. contact_groups 有很多联系人
  3. contact_contact_groups

列在 table 联系人

contact_id | contact_name

table 中的列 contact_groups

group_id | group_name

table 中的列 contact_contact_groups

contact_contact_group_id | contact_id | group_id

型号

联系人模型

public function getContactContactGroups()
{
    return $this->hasMany(ContactContactGroups::className(),
                          ['contact_id' => 'contact_id']);
}

contact_groups 型号

public function getContactContactGroups()
{
    return $this->hasMany(ContactContactGroups::className(),
                          ['group_id' => 'group_id']);
}

contact_contact_groups 模特

public function getGroup()
{
  return $this->hasOne(ContactGroups::className(), ['group_id' => 'group_id']);
}

public function getContact()
{
  return $this->hasOne(Contacts::className(), ['contact_id' => 'contact_id']);
}

我想像这样显示网格:

-----------------------------
Contact Name | Group Name
-----------------------------
Me           | Uncategorized
Mother       | Family
Jhon         | Business

VIEW

<?= GridView::widget([
  'dataProvider' => $dataProvider,
  'filterModel' => $searchModel,
  'tableOptions' =>['class' => 'table table-striped table-bordered'],
  'columns' => [
    [
      'attribute' => 'contact_name',
      'value' => 'contact_name',
    ],
    [
      'attribute' => 'contactContactGroups.group_id',
      'value' => 'contactContactGroups.group.group_name',
      'filter' => Html::activeDropDownList($searchModel, 'group_id', ArrayHelper::map(ContactGroups::find()->where(['group_status'=>'ACTIVE'])->asArray()->all(), 'group_id', 'group_name'),['class'=>'form-control','prompt' => 'Select Group']),
    ],
  ],]); 
?>

联系人控制器

public function actionIndex() { 
    $this->unsetThisButton(array(4,5));   
    $searchModel = new ContactsSearch(); 
    $dataProvider = $searchModel->search(Yii::$app->request->queryParams); 
    return $this->render('index', [ 
          'searchModel' => $searchModel, 
          'dataProvider' => $dataProvider,
     ]); 
}

但它显示 (not set) 而不是 group_name 。

一种简单的方法是在您的模型中添加一个 getter,例如:对于 contact_contact_groups 模型

你有关系

public function getGroup()
{
  return $this->hasOne(ContactGroups::className(), ['group_id' => 'group_id']);
}

对 group_name 使用 getter

 public function getGroup_group_name() {
    return $this->group->group_name;
}

并在网格视图中的属性中

[
  'attribute' => 'group_group_name',
  'filter' => Html::activeDropDownList($searchModel, 'group_id', ArrayHelper::map(ContactGroups::find()->where(['group_status'=>'ACTIVE'])->asArray()->all(), 'group_id', 'group_name'),['class'=>'form-control','prompt' => 'Select Group']),
],

对关系和字段执行相同的操作

我找到了像这样简单的东西:)

网格(视图)

[
        'attribute' => 'contactContactGroups.group_id',
        'value'=>function ($data) {
            $d = array();
            foreach ($data->contactContactGroups as $k=>$m)
            {
              $d[] = ContactContactGroups::get_group_name_by_id($m->group_id);
            }
            return implode($d, ', '); 
          },
        'filter' => Html::activeDropDownList($searchModel, 'group_id', ArrayHelper::map(ContactGroups::find()->where(['group_status'=>'ACTIVE'])->asArray()->all(), 'group_id', 'group_name'),['class'=>'form-control','prompt' => 'Select Group']),
      ],

models/ContactContactGroups.php 型号

我创建函数get_group_name_by_id($id)

public static function get_group_name_by_id($id){
  $model = ContactGroups::find()->where(["group_id" => $id])->one();
  if(!empty($model)){
    return $model->group_name;
  }
  return null;
}

所以结果是:

Contact   | Category
-------------------------------
Me        | Business, Family
Erick     | Business, Office
Jhon      | Office

谢谢@scaisEdge,你给我some clue ;)