CGridView with HAS_MANY-Relation

Hi,

I found a lot of similar topics, but no topic could help me.

I have two models, Data and Image. Data has many relations to Image.

I want to implement only one search for both models with CGridView.

DataController:




public function actionAdmin()

{

    $modelData=new Data('search');

    $modelData->unsetAttributes();  // clear any default values

    if(isset($_GET['Data']))

        $modelData->attributes=$_GET['Data'];


    $this->render('admin',array(

        'modelData'=>$modelData,

    ));

}



Data.php:




public function rules()

{

    return array(

        array('id, title, description, [b]image[/b]', 'safe', 'on'=>'search'),

    );

}


public function relations()

{

    return array(

        [b]'image' => array(self::HAS_MANY, 'Image', 'data_id'),[/b]

    );

}


public function search()

{

    $criteria=new CDbCriteria;


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

    $criteria->compare('title',$this->title,true);

    $criteria->compare('description',$this->description,true);

    [b]$criteria->compare('image',$this->image[0]->image,true);[/b]


    return new CActiveDataProvider($this, array(

        'criteria'=>$criteria,

    ));

}



admin.php:




<?php $this->widget('zii.widgets.grid.CGridView', array(

    'id'=>'data-grid',

    'dataProvider'=>$modelData->search(),

    'filter'=>$modelData,

    'columns'=>array(

        'id',

        'title',

        'description',

        'create_date',

        [b]'image.0.image',[/b]

        array(

            'class'=>'CButtonColumn',

        ),

),

)); ?>



_search.php:




<div class="row">

    [b]<?php echo $form->label($modelData,'image'); ?>

    <?php echo $form->textField($modelData,'image[0]'); ?>[/b]

</div>



The output is correct (see attachment), but the search doesn’t work.

I tried a lot of other code snippets (e.g. $criteria->with(), etc.), but the same result.

I hope you can help me.

Thanks a lot.

Motte

Hi Motte,

Introducing a virtual attribute for searching will make things easier for you. :)

Data.php:




// a virtual attribute for searching image

public $imageSearch;


public function rules()

{

    return array(

        array('id, title, description, imageSearch', 'safe', 'on'=>'search'),

    );

}


public function search()

{

    $criteria=new CDbCriteria;


    // search with 'image' relation

    $criteria->with = array('image');

    $criteria->together = true;


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

    $criteria->compare('title',$this->title,true);

    $criteria->compare('description',$this->description,true);

    $criteria->compare('image.image',$this->imageSearch,true);


    return new CActiveDataProvider($this, array(

        'criteria'=>$criteria,

    ));

}



admin.php:




<?php $this->widget('zii.widgets.grid.CGridView', array(

    'id'=>'data-grid',

    'dataProvider'=>$modelData->search(),

    'filter'=>$modelData,

    'columns'=>array(

        'id',

        'title',

        'description',

        'create_date',

        array(

            'name'=>'imageSearch',

            'value'=>'$data->image[0]->image',

        array(

            'class'=>'CButtonColumn',

        ),

),

)); ?>



_search.php:




<div class="row">

    <?php echo $form->label($modelData,'imageSearch'); ?>

    <?php echo $form->textField($modelData,'imageSearch'); ?>

</div>



Please note that the code above is not a complete solution.

There are difficult problems when you want to search by HAS_MANY relation. :(

Hi,

Thanks for your reply.

But it works also with HAS_MANY relation, at least in my case.

Is the solutions with a virtual attribute good style or just an easier solution?

Motte

I think it’s a common solution.

http://www.yiiframework.com/wiki/281/searching-and-sorting-by-related-model-in-cgridview

That’s fine.

About the possible problems and workarounds, please read the conversation between JimLam and redguy in the latest comments on the wiki above mentioned. :)