Yii 1.1: two or more different collected data in one CGridView

6 followers

Assume that you have teachers and students model.

teacher model has: 
- person_id,
- id_teacher,
- name,
- surname,
- bachelor,
- master,
... etc
 
student model has: 
- person_id,
- id_student,
- name,
- surname,
- age,
- apartment

(person_id is a global id both of teachers and students)

Now we want a CArrayProvider like that

PERSON DETAILS

person_id, id, name,  surname, bachelor, master, age, apartment
 
1           1  name1  surname1   yes       no     -       -
 
2           2  name2  surname2   yes      yes     -       -
 
3           1  name3  surname3    -        -     23    engineer
 
4           2  name4  surname4    -        -     25    doctor
 
5           3  name5  surname5    no      yes    -       -

How to achieve that?

This is a code that I used for a project

$t1 = Teachers::model()->findAll();
        $t2 = Students::model()->findAll();
 
 
        //prepair column's header (easy way)
        if (isset($t1[0]))
            $h = array_flip(array_keys($t1[0]->attributes));
 
        if (isset($t2[0]))
            $h = array_merge($h, array_flip(array_keys($t2[0]->attributes)));
 
        foreach ($h as $k => $v) {
            $h[$k] = null;
        }
 
        //collect the data using common key
        $res = array();
        foreach ($t1 as $v) {
            $res[$v->person_id] = $h;
            $res[$v->person_id] = array_merge($h, $v->attributes);
        }
 
        //merge with second data collection
        $test = 0;
        foreach ($t2 as $v) {
          $res[$v->person_id] = array_merge(isset($res[$v->person_id]) ? $res[$v->person_id] :   array(), $v->attributes);
        }
 
        //convert to CArrayDataProvider
        $dataProviderCompined = new CArrayDataProvider($res, array(
                    'pagination' => array(
                        'pageSize' => 10,
                    ),
                ));
 
 
 
        //display the data on CGridView
        $this->widget('zii.widgets.grid.CGridView', array(
            'id' => 'cost-grid-detail',
            'dataProvider' => $dataProviderCompined,
            'columns' => array(
                'person_id',
                'id',
                'name',
                'surname',
                'bachelor',
                'master',
                'age',
                'apartment'
            ),
        ));

Total 2 comments

#15438 report it
KonApaz at 2013/11/09 02:40pm
Re: Or use outer join

Yes you are right!

In my first thought I tried to do that you mentioned.

but in my real case I have already make dataproviders for other use and I wanted to extend my functionality without make new complex query.

My previous dataprovides uses complex queries and already edited from php code for the final results

Also imagine that some data may not exists in database (xml,memory, json, etc or php code)

So, I wrote this wiki for these cases (regardless of using directly findAll() )

With simple raw data yes you can do it with left,right,outer etc join :)

#15437 report it
tomvdp at 2013/11/09 02:23pm
Or use outer join

All this logic can be handled by the database engine. Look up what "outer join" does. (or am I missing something here?)

Leave a comment

Please to leave your comment.

Write new article