Reputation: 235
I'm quite new in Yii and I would like to know if this problem can be resolved in yii framework. I have three tables (A,B,C), A has the primary key 'a_id', B and C have a link to A (for example: b_a_id, c_a_id) that is a foreign key to 'a_id', relation A-B is one-to-one, relation A-C is one-to-many.
Is it possible in Yii in a simple way to have:
1) for relation A - B, an index-page with search bar for every field that displays all the field of A and B
2) for relation A - C, an index-page with search bar for every field that displays all the field of A and c
3) the same for A - B - C
??
I'm not interested in CREATE/UPDATE/DELETE operation, only INDEX with SEARCH
I has been able to show A-B relation using B Controller/Model/View displaying the index page with A fields and B fields. I used a code like that below
<?= GridView::widget([
'dataProvider' => $dataProviderB,
'filterModel' => $searchModelB,
'columns' => [
//['class' => 'yii\grid\SerialColumn'],
'b_id',
'b_field1',
'b_field2',
'b_a_id.a_field1', //field of B table
'b_a_id.a_field2',
'b_a_id.d_id.field1', //also field of D table liked to B
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
But It's not available search box on 'b_a_id.a_field1', 'b_a_id.a_field2' neither obviously on 'b_a_id.d_id.field1'. I know why. Because using foreign kwy i would like to show more than one field.
Do you have any suggestion for this kind of problem? Should I build a join sql command and display it? And so would the search available? Should I build a view in mysql database and generate model from view?
Please, reply with accuracy because I'm new in Yii
Thanks in advance
Upvotes: 1
Views: 1510
Reputation: 1004
You will need to change your searchModel (the one generated by GII when you made the crud).
in your view first change into,
<?= GridView::widget([
'dataProvider' => $dataProviderB,
'filterModel' => $searchModelB,
'columns' => [
//['class' => 'yii\grid\SerialColumn'],
'b_id',
'b_field1',
'b_field2',
['attribute'=>'afield1','value'=>'b_a_id.a_field1'], //so you have an easy tag to refer to in the searchmodel
['attribute'=>'afield2','value'=>'b_a_id.a_field2'],
//left out the one to D, should be analog
['class' => 'yii\grid\ActionColumn'],
],
Now in your searchModel you need to do a few steps, first off all, inside the class add
public $afield1 //the tag we used in the grid
public $afield2
Then add them in the rules
public function rules(){
return [
...,
[[...,'afield1','afield2'],'safe'],
...,
];
}
Then inside the search function, join a to b, and tell the dataProvider how the handle the sort
$query = b:find();
$query->joinWith('b_a_id');//join the table
$dataProvider = ...;
$this->load($params);
$dataProvider->sort->attributes['afield1'] = [
'asc'=>['b_a_id.a_field1'],
'desc'=>['b_a_id.a_field1']
] // tell how to sort
and finally, where the query is add an 'andFilterWhere' as such
$query->andFilterWhere([...])
...
->andFilterWhere(['like','b_a_id.a_field1']);
It's also possible to sort on one-to-many / many-to-many relationships in a similar way, except you need to join more, and you need to define a 'getOneToManyDisplay' method in the model that transform that relationship into a string, but otherwise works in a similar way
Upvotes: 4