How to show relational data in yii2
Solution 1
You can also add columns to a gridview with value from an anonymous function as described here http://www.yiiframework.com/doc-2.0/yii-grid-datacolumn.html#$value-detail. For example you can show an author's name like this in a gridview:
<?= GridView::widget([
'dataProvider'=>$dataProvider,
'filterModel'=>$searchModel,
'columns'=>[
[
'attribute'=>'author.name',
'value'=>function ($model, $key, $index, $column) {
return $model->author->name;
},
],
//...other columns
]);
?>
you can also return a html-link to the detail-view of an author like this:
//...
'columns'=>[
[
'attribute'=>'author',
'value'=>function ($model, $key, $index, $column) {
return Html::a($model->author->name, ['/author/view', 'id'=>$model->author->id]);
},
],
//...
],
//...
Solution 2
You can access relation table data in any crud view file using their relation name. $model->relName->attribute_name.
And You can access relation table data in gridview at following way :
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
[
'attribute' => 'author',
'value'=>'author.author_name', //relation name with their attribute
]
],
]);
Solution 3
First you need a get function in your model, but you have.
This is :
public function getAuthor()
{
return $this->hasOne(Author::className(), ['id' => 'author']);
}
Now you just need do one more thing.
Go to the index file, and to GridView, and columns.
Write this into columns:
[
'attribute' => 'author',
'value' => 'author.name',
],
In the value, the first parameter is your Get function, what named is : getAuthor, and .
after your column name.
TEster
Updated on July 31, 2022Comments
-
TEster almost 2 years
I'm having trouble understanding how relations work in yii 2
I have 2 tables in a mysql database, author and book.
book has a column named author which links to the id of the author table via foreign key.
I've generated CRUD using gii, and I want the author name to appear in the list view, as well as dropdowns for the author name in the create and update views.
But I cant seem to get the relation working even in the list view.
Here's my code
Book Model:
<?php namespace app\models; use Yii; use app\models\Author; /** * This is the model class for table "book". * * @property integer $id * @property string $name * @property integer $author */ class Book extends \yii\db\ActiveRecord { /** * @inheritdoc */ public static function tableName() { return 'book'; } /** * @inheritdoc */ public function rules() { return [ [['name', 'author'], 'required'], [['author'], 'integer'], [['name'], 'string', 'max' => 11] ]; } /** * @inheritdoc */ public function attributeLabels() { return [ 'id' => 'ID', 'name' => 'Name', 'author' => 'Author', ]; } public function getAuthor() { return $this->hasOne(Author::className(), ['id' => 'author']); } }
BookSearch Model:
<?php namespace app\models; use Yii; use yii\base\Model; use yii\data\ActiveDataProvider; use app\models\Book; /** * BookSearch represents the model behind the search form about `app\models\Book`. */ class BookSearch extends Book { /** * @inheritdoc */ public function rules() { return [ [['id', 'author'], 'integer'], [['name'], 'safe'], ]; } /** * @inheritdoc */ public function scenarios() { // bypass scenarios() implementation in the parent class return Model::scenarios(); } /** * Creates data provider instance with search query applied * * @param array $params * * @return ActiveDataProvider */ public function search($params) { $query = Book::find(); $query->joinWith('author'); $dataProvider = new ActiveDataProvider([ 'query' => $query, ]); var_dump($dataProvider); if (!$this->validate()) { // uncomment the following line if you do not want to return any records when validation fails // $query->where('0=1'); return $dataProvider; } $query->andFilterWhere([ 'id' => $this->id, 'author' => $this->author, ]); $query->andFilterWhere(['like', 'name', $this->name]); return $dataProvider; } }
Also, here's the view file:
<?php use yii\helpers\Html; use yii\grid\GridView; /* @var $this yii\web\View */ /* @var $searchModel app\models\BookSearch */ /* @var $dataProvider yii\data\ActiveDataProvider */ $this->title = 'Books'; $this->params['breadcrumbs'][] = $this->title; ?> <div class="book-index"> <h1><?= Html::encode($this->title) ?></h1> <?php // echo $this->render('_search', ['model' => $searchModel]); ?> <p> <?= Html::a('Create Book', ['create'], ['class' => 'btn btn-success']) ?> </p> <?= GridView::widget([ 'dataProvider' => $dataProvider, 'filterModel' => $searchModel, 'columns' => [ ['class' => 'yii\grid\SerialColumn'], 'id', 'name', [ 'attribute' => 'author', 'value' => 'author.name', ], ['class' => 'yii\grid\ActionColumn'], ], ]); ?> </div>
Author Model:
<?php namespace app\models; use Yii; /** * This is the model class for table "author". * * @property integer $id * @property string $name */ class Author extends \yii\db\ActiveRecord { /** * @inheritdoc */ public static function tableName() { return 'author'; } /** * @inheritdoc */ public function rules() { return [ [['name'], 'required'], [['name'], 'string', 'max' => 200] ]; } /** * @inheritdoc */ public function attributeLabels() { return [ 'id' => 'ID', 'name' => 'Name', ]; } }
I think I may have to change something somehwhere in the author/authorSearch model.
Can someone help
thanks