Crud - Show Hasone Relation In Gridview

Hi

I’ve got two models, eg A and B

B has a function called getA() that returns an \yii\db\ActiveRelation:




public function getA()

{

  return $this->hasOne(A::className(), ['id' => 'a_id']);

}



The B index action shows a standard GII GridView widget. But in one of the columns I want to show the name of A.

I’ve managed to get this working by defining a column:




'columns' => [

  ...

  array(

      'header' => 'A',

      'value' => function($value, $model, $index) {

        $a = A::find(['id' => $value->a]);

        return $a->name;

      },

  ),

  ...

],



This works, but I’m worried this executes way to many queries.

Is there an better way to display the name A in the gridview?

If you are worried about too many queries, I would suggest you change your [font="Courier New"]dataProvider[/font] itself (either use a DB View or a join query as source for your dataProvider and the search model).




$model->A->name;



your query execute just once

because of cache

CMIIW

Not quite. This executes n number of queries, where n = number of results in the grid search.

To optimize this, you’ll need to eager load the related data in the search model.




$query = $model::find();

$query->with("a"); // eager load data

$dataProvider = new ActiveDataProvider([

    'query' => $query,

]);



This will result in 2 queries:




select * from b

select * from a where a_id in (1,2,3,etc)



There have actually been several topics on GridView, so I wrote a tutorial on processing related model data. If you want to go further with sorting and filtering, check it out here.

Excellent! Works perfect.

For completeness also the change to the view:




'columns' => [

  ...

  array(

      'header' => 'A',

      'value' => function($value, $model, $index) {

        return $a->B->name;

      },

  ),

  ...

],



Nice! I’ve bookmarked this page!

Thnx!

Nice examples… you could put it on the wiki.