Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Search in BELONGS_TO model column with CGridView, Yii

Tags:

search

model

yii

I have a CGridView widget for Lesson model

$this->widget('zii.widgets.grid.CGridView', array(
     'id'=>'lesson-grid',
     'dataProvider'=>$model->search(),
     'filter'=>$model,

... and Lesson has relation to the User model:

'user' => array(self::BELONGS_TO, 'User', 'user_id'),

... and the CGridView has a column with user's lastname from the BELONGS_TO model described above

'columns'=>array(
        ...
        array(
            'name' => 'user',
            'header'=>'Teacher',
            'value' => '$data->user->lastname',
        ),

So, I can't symply search with CGridView in this column, but I need it.

How to search in '$data->user->secondname' with CGridView?

I think that I should extend search method in Lesson model, but how?

Now it looks like this:

public function search()
{
    // Warning: Please modify the following code to remove attributes that
    // should not be searched.

    $criteria=new CDbCriteria;

    $criteria->compare('id',$this->id);
    $criteria->compare('student',$this->student,true);
    $criteria->compare('comment',$this->comment,true);

    return new CActiveDataProvider(get_class($this), array(
        'criteria'=>$criteria,
    ));
}
like image 227
Kir Avatar asked Feb 25 '23 05:02

Kir


1 Answers

This should work, add it to your search criteria in the search() method:

$criteria->with[]='user';
$criteria->addSearchCondition("user.secondname",$this->user_id);

This is what I do though:

if(!intval($this->user_id) && is_string($this->user_id) && strlen($this->user_id) > 0) {
  $criteria->with[]='user';
  $criteria->addSearchCondition("user.secondname",$this->user_id);
} else
  $criteria->compare('t.user_id',$this->user_id);

And here is the CGridView definition:

'columns'=>array(
  ...
  array(
    'name' => 'user_id',
    'header'=>'User',
    'sortable'=>false, // since it would still be sorting based on ID
    // 'value' => '$data->user->lastname', // basic version
    'value'=>'CHtml::link((isset($data->user))?$data->user->username:$data->user_id,array("user/view","id"=>$data->user_id))', // link version
    ),

It's a fun little trick: if the search term is a string and NOT an intval(), it searches for the user by their secondname, via the "user" relation. But if you enter a user_id, it will find the user by their user_id - the default search() functionality.

NOTE: This will enable filtering, but it will still sort based on ID. You will need to implement something additional to get the sorting to work.

There are surely other ways to do this, but this is how I do it. I suspect there is a "right" to do this using the relation, but my technique works solid.

like image 54
thaddeusmt Avatar answered Mar 05 '23 18:03

thaddeusmt