Cgridview Filter With Multiple Models

Hello every1,

i don’t know if some of you have met a problem, when they have a CGridView with Models, that have a HAS_MANY relationship and you need to select 1 of this MANY objects. I would like just to share my code, if someone will stuck in the same problem.

  1. In my model i have declared an attribute ‘contact’:



class Customer extends CActiveRecord

{

	public $contact = '';



  1. This is my GridView:




<?php

$this -> widget('bootstrap.widgets.TbGridView', array(

	'type' => 'striped bordered condensed',

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

	'filter'=> $model,

	'template' => "{items}{pager}",

	'rowCssClassExpression' => 'CustomerController::setRowColor($data->warningStatus)',

	'columns' => array(

			array(

					'name'=>'id',

					'htmlOptions' => array(

							'style' => 'width:100px;'

					)

			),

			'title',

			array(

					'name'=>'contact',

					'type'=>'raw',

			),

			'group_id',

			array(

					'class' => 'bootstrap.widgets.TbButtonColumn',

					'htmlOptions' => array('style' => 'width: 50px'),

			),

	),

));

?>



My model has a relation named Contacts(HAS_MANY) but i need only 1 Contact that is active right now and show its First name, Last Name and code it as a Link binded to E-Mail.

  1. Model Search Function:



public function search()

{

	// Warning: Please modify the following code to remove attributes that

	// should not be searched.

	if(isset($_GET['Customer']['contact']))

		$this->contact = $_GET['Customer']['contact'];


	$criteria=new CDbCriteria;

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

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

	$customers = Customer::model()->findAll($criteria);


	foreach($customers as $key=>$customer) {

		$contact = Contact::model()->findByAttributes(array(),'customer_id='.$customer->id.' AND standard=1');

		if(empty($contact))

			$contact = Contact::model()->findByAttributes(array(),'customer_id='.$customer->id);

		if(!empty($contact)) {

			if(strlen($this->contact)==0 || strpos($contact->email,$this->contact)===0 ||

					strpos($contact->firstname,$this->contact)===0 ||

					strpos($contact->lastname,$this->contact)===0 ||

					($contact && strlen($this->contact)==0))

				$customer->contact = '<a href="mailto:'.$contact->email.'">'.$contact->firstname.' '.$contact->lastname.'</a>';

			else

				unset($customers[$key]);

		}

	}


	return new CActiveDataProvider($this, array(

			'data'=>$customers,

			'sort'=>array(

					'attributes'=>array(

							'contact'=>array(

									'asc'=>'contact',

									'desc'=>'contact DESC',

							),

							'*',

					),

			),

	));

}