template php entity-relationship yii2

template - PHP, Yii2 GridView filtrando en valor relacional



yii2 gridview template (3)

Siguiendo de esto:

Yii2 ¿cómo funciona search () en SearchModel?

Me gustaría poder filtrar una columna GridView de datos relacionales. Esto es lo que quiero decir:

Tengo dos tablas, TableA y TableB . Ambos tienen modelos correspondientes generados usando Gii. TableA tiene una clave externa a un valor en TableB , como este:

TableA attrA1, attrA2, attrA3, TableB.attrB1 TableB attrB1, attrB2, attrB3

attrA1 y attrB1 son las claves primarias de sus tablas correspondientes.

Ahora, tengo un Yii2 GridView de attrA2 , attrA3 y attrB2 . Tengo un filtro de trabajo en attrA2 y attrA3 para poder buscar en los valores de columna. También tengo una clasificación de trabajo para estas dos columnas, simplemente haciendo clic en el encabezado de la columna. Me gustaría poder agregar este filtrado y clasificación en attrB2 también.

Mi modelo TableASearch ve así:

public function search($params){ $query = TableA::find(); $dataProvider = new ActiveDataProvider([ ''query'' => $query, ]); if (!($this->load($params) && $this->validate())) { return $dataProvider; } $this->addCondition($query, ''attrA2''); $this->addCondition($query, ''attrA2'', true); $this->addCondition($query, ''attrA3''); $this->addCondition($query, ''attrA3'', true); return $dataProvider; }

En mi modelo TableA , establezco el valor relacionado como este

public $relationalValue; public function afterFind(){ $b = TableB::find([''attrB1'' => $this->attrB1]); $this->relationalValue = $b->relationalValue; }

Aunque probablemente no sea la mejor manera de hacerlo. Creo que tengo que usar $ relationalValue en algún lugar de mi función de búsqueda, pero no estoy seguro de cómo. Del mismo modo, me gustaría poder ordenar por esta columna también, al igual que puedo para attrA2 y AttrA3 haciendo clic en el enlace del encabezado`. Cualquier ayuda sería apreciada. Gracias.


Esto se basa en la descripción en la guide . El código base para el SearchModel proviene del generador de código Gii. Esto también se supone que $ this-> TableB se ha configurado utilizando la relación hasOne() o hasMany() . Ver este doc .

1. Configurar el modelo de búsqueda

En el modelo TableASearch agregar:

public function attributes() { // add related fields to searchable attributes return array_merge(parent::attributes(), [''TableB.attrB1'']); } public function rules() { return [ /* your other rules */ [[''TableB.attrB1''], ''safe''] ]; }

Luego, en TableASearch->search() agregue (antes de $this->load() ):

$dataProvider->sort->attributes[''TableB.attrB1''] = [ ''asc'' => [''TableB.attrB1'' => SORT_ASC], ''desc'' => [''TableB.attrB1'' => SORT_DESC], ]; $query->joinWith([''TableB'']);

Luego, la búsqueda real de sus datos (debajo de $this->load() ):

$query->andFilterWhere([''like'',''TableB.attrB1'',$this->getAttribute(''TableB.attrB1''));

2. Configurar GridView

Añade a tu vista:

echo GridView::widget([ ''dataProvider'' => $dataProvider, ''filterModel'' => $searchModel, ''columns'' => [ /* Other columns */ ''TableB1.attrB1'', /* Other columns */ ] ]);


Estoy atascado con este problema también, y mi solución es bastante diferente. Tengo dos modelos simples:

Libro:

class Book extends ActiveRecord { .... public static function tableName() { return ''books''; } public function getAuthor() { return $this->hasOne(Author::className(), [''id'' => ''author_id'']); }

Y Autor:

class Author extends ActiveRecord { public static function tableName() { return ''authors''; } public function getBooks() { return $this->hasMany(Book::className(), [''author_id'' => ''id'']); }

Pero mi lógica de búsqueda está en un modelo diferente. Y no encontré cómo puedo implementar la búsqueda sin crear un campo adicional author_first_name . Así que esta es mi solución:

class BookSearch extends Model { public $id; public $title; public $author_first_name; public function rules() { return [ [[''id'', ''author_id''], ''integer''], [[''title'', ''author_first_name''], ''safe''], ]; } public function search($params) { $query = Book::find()->joinWith([''author'' => function($query) { $query->from([''author'' => ''authors'']);}]); $dataProvider = new ActiveDataProvider([ ''query'' => $query, ''pagination'' => array(''pageSize'' => 50), ''sort''=>[ ''attributes''=>[ ''author_first_name''=>[ ''asc'' => [''author.first_name'' => SORT_ASC], ''desc'' => [''author.first_name'' => SORT_DESC], ] ] ] ]); if (!($this->load($params) && $this->validate())) { return $dataProvider; } .... $query->andWhere([''like'', ''author.first_name'', $this->author_first_name]); return $dataProvider; } }

Esto es para crear el alias de la tabla: function($query) { $query->from([''author'' => ''authors'']);}

Y el código de GridView es:

<?php echo GridView::widget([ ''dataProvider'' => $dataProvider, ''filterModel'' => $searchModel, ''columns'' => [ [ ''attribute'' => ''id'', ''filter'' => false, ], [ ''attribute'' => ''title'', ], [ ''attribute'' => ''author_first_name'', ''value'' => function ($model) { if ($model->author) { $model->author->getFullName(); } else { return ''''; } }, ''filter'' => true, ], [''class'' => ''yii/grid/ActionColumn''], ], ]); ?>

Apreciaré cualquier crítica y consejo.


Filtrar una vista de cuadrícula por una columna es muy fácil en Yii 2.0. Agregue el atributo de filtro a una columna de vista de cuadrícula que tenga valores de búsqueda, como en:

[ "class" => yii/grid/DataColumn::className(), "attribute" => "status_id", ''filter'' => ArrayHelper::map(Status::find()->orderBy(''name'')->asArray()->all(), ''id'', ''name''), "value" => function($model){ if ($rel = $model->getStatus()->one()) { return yii/helpers/Html::a($rel->name,["crud/status/view", ''id'' => $rel->id,],["data-pjax"=>0]); } else { return ''''; } }, "format" => "raw", ],