Intereting Posts
Как вызвать конструктор родительских классов с его исходными параметрами в PHP Как удалить или обрезать специальные символы (\ n) из массива? Как я могу заставить Flash обмениваться файлами cookie браузера / сеансом? Шифрование / расшифровка RSA, совместимая с Javascript и PHP Хранение хэшированного идентификатора в БД и извлечение его или создание хэшированного идентификатора в самом коде и его использование? PHP cURL для одновременного сохранения изображения и получения ответа заголовка Запуск тестов PHPUnit в определенном порядке предотвращать прямой доступ к php PHP.net говорит, что md5 () и sha1 () непригодны для пароля? Regex соответствует имени класса CSS Есть ли разумный способ запуска нескольких запросов в mysql, разделенных точкой с запятой; Настройка переменных сеанса PHP с помощью Flash ActionScript Захват ошибок компиляции регулярных выражений PHP – Загрузка нескольких изображений Размер не отображается при загрузке файлов с моего сайта

PHP, Yii2 Фильтрация GridView по реляционной ценности

Исходя из этого:

Yii2 Как работает поиск () в SearchModel?

Я хотел бы иметь возможность фильтровать столбец GridView реляционных данных. Это то, что я имею в виду:

У меня есть две таблицы, TableA и TableB . Оба имеют соответствующие модели, сгенерированные с использованием Gii. TableA имеет внешний ключ для значения в TableB , например:

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

attrA1 и attrB1 являются первичными ключами соответствующих таблиц.

Теперь у меня есть Yii2 GridView attrA2 , attrA3 и attrB2 . У меня есть рабочий фильтр на attrA2 и attrA3 чтобы я мог искать значения столбцов. У меня также есть рабочий вид для этих двух столбцов – просто щелкнув заголовок столбца. Я хотел бы иметь возможность добавлять эту фильтрацию и сортировку на attrB2 тоже.

Моя модель TableASearch выглядит так:

 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; } 

В моей модели TableA я устанавливаю соответствующее значение следующим образом

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

Хотя это, вероятно, не лучший способ сделать это. Я думаю, что мне нужно использовать $ relationalValue где-то в моей функции поиска, но я не уверен, как это сделать. Аналогично, я хотел бы иметь возможность сортировать по этому столбцу тоже – так же, как я могу для attrA2 и AttrA3 , нажав на ссылку заголовка`. Любая помощь будет оценена по достоинству. Благодарю.

Фильтрация сетки в столбце в Yii 2.0 проста. Добавьте атрибут фильтра в столбец gridview со значениями поиска, как показано ниже:

 [ "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", ], 

Это основано на описании в руководстве . Базовый код для SearchModel поступает из генератора кода Gii. Это также предполагает, что $ this-> TableB был настроен с использованием отношения hasOne() или hasMany() . См. Этот документ .

1. Настроить поисковую модель

В модели TableASearch добавьте:

 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'] ]; } 

Затем в TableASearch->search() добавьте (до $this->load() ):

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

Затем фактический поиск ваших данных (ниже $this->load() ):

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

2. Настройте GridView

Добавить к вашему мнению:

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

Я тоже застрял в этой проблеме, и мое решение совсем другое. У меня две простые модели:

Книга:

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

И Автор:

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

Но моя логика поиска находится в другой модели. И я не нашел, как я могу реализовать поиск без создания дополнительного поля author_first_name . Итак, это мое решение:

 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; } } 

Это для создания псевдонима таблицы: function($query) { $query->from(['author' => 'authors']);}

И код GridView:

 <?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'], ], ]); ?> 

Буду признателен за любые критические замечания и советы.