Search code examples
mysqlyii2cgridview

How to join three tables and get value in grid view


I have three tables :

  1. contacts hasMany groups
  2. contact_groups hasMany contacts
  3. contact_contact_groups

columns in table contact

contact_id | contact_name

columns in table contact_groups

group_id | group_name

columns in table contact_contact_groups

contact_contact_group_id | contact_id | group_id

MODEL

contacs model

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

contact_groups model

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

contact_contact_groups model

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

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

I want to display grid like this :

-----------------------------
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']),
    ],
  ],]); 
?>

ContactsController

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,
     ]); 
}

But it showing (not set) not a group_name .


Solution

  • I Found simple stuff like this :)

    GRID (VIEW)

    [
            '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 Model

    I create function 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;
    }
    

    so the result is :

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

    Thank's @scaisEdge, you give me some clue ;)