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:


        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.


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( ' IN (SELECT release_id FROM release_artists WHERE artist_id IN(' . $artists . '))');


Works a treat! :slight_smile: