0
votes

I am having quiet a bit of problem displaying HAS MANY relation within a CGridView.

I want to display all the post titles for a particular author in CGridView seperated by a ',' (comma).

Here's a simple example:

I have the following tables:

author:id,name

post:id,title,created(DATETIME),a_id.

Post belongs to Author through a_id.

Model:

    public $postTitles;

    public function relations()
    {
            // NOTE: you may need to adjust the relation name and the related
            // class name for the relations automatically generated below.
            return array(
                    'posts' => array(self::HAS_MANY, 'Post', 'a_id'),
            );
    }

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

            $criteria=new CDbCriteria;

            $criteria->select="t.*,title AS postTitles";
            $criteria->join="LEFT OUTER JOIN post on a_id=t.id";

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

            return new CActiveDataProvider($this, array(
                    'criteria'=>$criteria,
                    'sort'=>array("attributes"=>array(
                            'id',
                            'name',
                               )),
            ));
    }

    public function getPostTitles() {
            $return = ',';
            foreach ($this->posts as $post) {
                    $return .= $post->title;
            }
            return $return;
    }

Controller:

    public function actionIndex()
    {
            $model = new Author('search');
            $this->render('index', array('model' => $model));
    }

View:

    $this->widget('zii.widgets.grid.CGridView', array(
        'id'=>'author-grid',
        'dataProvider'=>$model->search(),
        'filter'=>$model,
        'columns'=>array(
            'id',
            'name',
            array(
                    'id'=>'postTitles',
                    'type'=>'raw',
                    'value'=> array($model, 'getPostTitles'), 
            ),

            array(
                    'class'=>'CButtonColumn',
            ),
        ),
    )); 
1

1 Answers

1
votes

in Author model, you can write a function that will give you names of the titles,

public function getAuthorsPostTitles()
{
    $text = 'no title yet';

    if(!empty($this->posts)) // if this Author has any related Posts
    {
        $counter = 0;
        foreach($this->posts as $post)
        {
            if($counter == 0) 
               $text = $post->title;
            else
               $text .= ', ' . $post->title;
        }
    }
    return $text;    
}

an then in your grid you can use it:

array(
      'header'=>'Post Titles',
      'value'=> '$data->getAuthorsPostTitles()', 
),