Filter setup for related model in GridView
Actually it is much simpler than it seems.
add the
column_name
to safe attribute. Note: this should be relation Nameadd the join with query - like -
$query->joinWith(['serviceName','roomCategory']);
add the filter condition like:
->andFilterWhere(['like', 'services.services', $this->service_name]) ->andFilterWhere(['like', 'room_category.room_category', $this->room_category]);
if like to add sorting add the code like:
$dataProvider->sort->attributes['service_name'] = [ 'asc' => ['services.services' => SORT_ASC], 'desc' => ['services.services' => SORT_DESC], ]; $dataProvider->sort->attributes['room_category'] = [ 'asc' => ['room_category.room_category' => SORT_ASC], 'desc' => ['room_category.room_category' => SORT_DESC], ];
5 you should also set the relation name say public $roomCategory
That's it. Both sorting and filtering for related table works perfectly.
Note: Remove default validation like integer for related column and default filtering generated by gii
otherwise it will generate an error.
Update on Latest version:
- Adding Public $attribute is not needed.
- Adding safe attribute for relation is also not needed.
- but the attribute in your current model, which you want filter is to added to safe attribute that is a must.
- and most importantly in your gridview, the related attribute has to be in closure format.
that is example
[
'attribute=>'attribute_name',
'value=function($data){
return $data->relationname->related_table_attribute_name
}
],
remember it you are using relation_name.related_table_attribute_name
filter somehow doesn't work for me.
Related videos on Youtube
Comments
-
Pawan almost 2 years
I am trying to setup the filter for related model in Yii2's GridView widget, but I am keep getting the error like the filter value must be an integer.
I have followed this question. Now, I have a two models
Services.php
andServiceCharge.php
.In
ServiceCharge.php
the relation is setup like:public function getServiceName() { return $this->hasOne(Services::className(),['id'=>'service_name']); }
In the
ServiceChargeSearch.php
the code is like this:<?php namespace app\models; use Yii; use yii\base\Model; use yii\data\ActiveDataProvider; use app\models\ServiceCharges; /** * ServiceChargesSearch represents the model behind the search form about `app\models\ServiceCharges`. */ class ServiceChargesSearch extends ServiceCharges { /** * @inheritdoc */ public function attributes() { // add related fields to searchable attributes return array_merge(parent::attributes(), ['serviceName.services']); } public function rules() { return [ [['id'], 'integer'], [['charges_cash', 'charges_cashless'], 'number'], [['id', 'serviceName.services', 'room_category'], '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 = ServiceCharges::find(); $dataProvider = new ActiveDataProvider([ 'query' => $query, ]); $dataProvider->sort->attributes['serviceName.services'] = [ 'asc' => ['serviceName.services' => SORT_ASC], 'desc' => ['serviceName.services' => SORT_DESC], ]; $query->joinWith(['serviceName']); $this->load($params); if (!$this->validate()) { // uncomment the following line if you do not want to any records when validation fails // $query->where('0=1'); return $dataProvider; } $query->andFilterWhere([ 'id' => $this->id, // 'service_name' => $this->service_name, 'room_category' => $this->room_category, 'charges_cash' => $this->charges_cash, 'charges_cashless' => $this->charges_cashless, ]) ->andFilterWhere(['LIKE', 'serviceName.services', $this->getAttribute('serviceName.services')]); return $dataProvider; } }
and in my Gridview it is setup like this:
[ 'attribute'=>'service_name', 'value'=>'serviceName.services', ],
Which is showing the services name from the related model correctly.
I am not able to see what I am doing wrong, but the filter field for the attribute for service is not showing at all.