Search code examples
searchyiicgridview

Search through related model in Yii


I have a problem with searching in Yii. I have two models: Teams and Workers. On website there is a page called 'Team Workers' where I want to display CGridView widget with searching that displays Workers from the team (team id is passed as a _GET parameter).

I did this in TeamsController:

public function actionWorkers($id)
{
    $model = Teams::model()->findByPk($id);
    $workers = Workers::model();
    $workers->unsetAttributes();
    if(isset($_GET['Workers']))
    {
        $_GET['Workers']['idTeam'] = $id;
        $workers->attributes = $_GET['Workers'];
    }
    else {
        $workers->attributes = array('idTeam' => $id);
    }

    $teamWorkers = $workers;
    $this->render('workers', array(
        'model' => $model,
        'teamWorkers' => $teamWorkers
    ));
}

And in the view file:

<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'team-workers-grid',
'dataProvider'=>$teamWorkers->search(),
'filter' => $teamWorkers,
'columns'=>array(
    'name',
    'surname',
    array(
        'id' => 'idWorker',
        'class' => 'CCheckBoxColumn',
        'checked' => '$data->confirmer',
        'selectableRows' => '2',
        // 'headerTemplate' => '{item}'
    )
),
)); ?>

I got the error:

CDbCommand nie zdołał wykonać instrukcji SQL: SQLSTATE[23000]: Integrity constraint
violation: 1052 Column 'idTeam' in where clause is ambiguous. The SQL statement 
executed was: SELECT COUNT(DISTINCT `t`.`idWorker`) FROM `workers` `t` LEFT OUTER JOIN 
`teams` `Team` ON (`t`.`idTeam`=`Team`.`idTeam`) WHERE ((idTeam=:ycp0) AND (Team.name 
LIKE :ycp1)) 

When I dont set idTeam attribute - it works fine. It's pretty weird - at the regular CRUD admin page - idTeam attribute is passed and that works fine.

Hot to deal with it?


Solution

  • In Workers::search() you have something like

    $criteria->compare('idTeam',$this->idTeam);
    

    Change it to

    $criteria->compare('t.idTeam',$this->idTeam);
    

    i.e prefix sql attribute with t. if it is from current model or with relation name if from other table/model


    Also instead of:

    $workers->attributes = array('idTeam' => $id);
    

    yould could keep it simpler with:

    $workers->idTeam = $id;