cGridView Relations - third level

I’m working on a music application and have a cGridview to display music releases.

One of the columns is "Release Artists". My releases table/model has a HAS_MANY relation with a "release_artists" table:




    // Releases model

    public function relations()

    {

        return array(

            'releaseArtists' => array(self::HAS_MANY, 'ReleaseArtists', 'release_id'), ........



The “release_artists” table only stores ‘release_id’ and ‘artist_id’. Thus a release can have many individual artists. The “release_artists” table naturally has a relation with my “artists” table, thus the releaseArtists object which is returned with a Releases query contains all the data for each individual artist:




    //  ReleaseArtists model

	public function relations()

	{

		return array(

			'artist' => array(self::BELONGS_TO, 'Artists', 'artist_id'),

		);

	}    



For example, an individual artists name can be accessed from the releaseArtists object like this:




    foreach($data->releaseArtists as $val) {

       $artist = $val->artist->artist_name;

       echo $artist . ' ';

    }




As you can see, the releaseArtists object in turn has an ‘artist’ object for each individual artist.

To keep it clean, in my cGridview I call a function to output the artists for a release:




    'columns'=>array(

        array('name' => 'release_artists', 'type' => 'raw', 'value' => 'Releases::model()->outputLabelArtists($data->releaseArtists)'), ......



This works well. I would like however to introduce a search filter by artist name, so that if one of the artists for a release matches, that release will be filtered. The filter input already displays in my cGrid View and the Ajax works, however I am not sure how the search() function in my Releases model should be modified to make it all work.

Anybody?

I ended up doing it like this:

In my ‘Releases’ class at the top I added:




    public $release_artists;



In the ‘rules’ method I added ‘release_artists’ to the ‘search’ array;

I created a new method in my ‘Artists’ class:




	public function findArtists($text)

	{

		$sql = "SELECT id FROM artists WHERE artist_name LIKE '%" . Yii::app()->input->purify($text) . "%'"; 

                // I use a purifier extension

		$command = Yii::app()->db->createCommand($sql);

		$artists = $command->queryAll();

		$artist_array = array();

		foreach($artists as $val) {

			$artist_array[] = $val['id'];

		}

		

		$artist_list = implode(',', $artist_array);

		

		return $artist_list;

	}



Then in my ‘Releases’ model ‘search’ method I added the following:




    if(!empty($this->release_artists)) {

	$artists = Artists::model()->findArtists($this->release_artists);

	$criteria->addCondition( 't.id IN (SELECT release_id FROM release_artists WHERE artist_id IN(' . $artists . '))');

    }



Works a treat! :slight_smile: