@ZaurK

Как сделать сортировку по зависимому полю?

Здравствуйте! Голову сломал, и гугление ничего не дало - все, что нашел не очень подходит или не решает проблему. Есть модель товаров Good.php с внешней зависимостью от модели Catalog.php

public function getCatalog()
    {
        return $this->hasOne(Catalog::className(), ['id' => 'catalog_id']);
    }


Также есть вид для вывода информации по товарам, в третьей колонке выводятся соотвественно каталоги, к которым принадлежат товары

<?php

use yii\helpers\Html;
use yii\grid\GridView;

/* @var $this yii\web\View */
/* @var $searchModel backend\models\SearchGood */
/* @var $dataProvider yii\data\ActiveDataProvider */

$this->title = 'Работы';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="good-index">

    <h1><?= Html::encode($this->title) ?></h1>
    <?php // echo $this->render('_search', ['model' => $searchModel]); ?>

    <p>
        <?= Html::a('Добавление работы', ['create'], ['class' => 'btn btn-success']) ?>
    </p>
    <?= GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => [
            ['class' => 'yii\grid\SerialColumn'],

            //'id',
            [
                'attribute'=>'gtitle',
                'label'=>'Заголовок',    
            ],
            'gdescription:ntext',
            [
                'attribute'=>'catalog.ctitle',
                'label'=>'Каталог',
                
                
            ],
            // 'promo',

            ['class' => 'yii\grid\ActionColumn'],
        ],
    ]); ?>
</div>


Также есть SearchGood.php с таким кодом:

<?php

namespace backend\models;

use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use common\models\Good;

/**
 * SearchGood represents the model behind the search form about `common\models\Good`.
 */
class SearchGood extends Good
{
    public function attributes()
    {
    // делаем поле зависимости доступным для поиска
    return array_merge(parent::attributes(), ['catalog.ctitle']);
    }
    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['id', 'catalog_id', 'promo'], 'integer'],
            [['gtitle', 'gdescription', 'catalog.ctitle'], '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 = Good::find();

        // присоединяем зависимость `catalog` которая является связью с таблицей `catalog`
        // и устанавливаем алиас таблицы в значение `catalog`
        $query->joinWith(['catalog' => function($query) { $query->from(['catalog' => 'catalog']); }]);
        // добавляем сортировку по колонке из зависимости
        $dataProvider->sort->attributes['catalog.ctitle'] = [
        'asc' => ['catalog.ctitle' => SORT_ASC],
        'desc' => ['catalog.ctitle' => SORT_DESC],
        ];
        
        // add conditions that should always apply here

        $dataProvider = new ActiveDataProvider([
            'query' => $query,
        ]);

        $this->load($params);

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

        // grid filtering conditions
        $query->andFilterWhere([
            'id' => $this->id,
            'catalog_id' => $this->catalog_id,
            'promo' => $this->promo,
        ]);

        $query->andFilterWhere(['like', 'gtitle', $this->gtitle])
            ->andFilterWhere(['like', 'gdescription', $this->gdescription])
            ->andFilterWhere(['like', 'catalog.ctitle', $this->getAttribute('catalog.ctitle')]);

        return $dataProvider;
    }
}


Поиск работает по всем колонкам, проблема в том, что сортировка по калонке с каталогами не хочет работать, некликабельная ссылка "Каталог".
Прошу подсказать как доработать этот момент?
  • Вопрос задан
  • 180 просмотров
Решения вопроса 1
qonand
@qonand
Software Engineer
У Вас не работает сортировка потому что:
// тут Вы задаете атрибуты сортировки в переменной в которой еще нет объекта провайдера данных
$dataProvider->sort->attributes['catalog.ctitle'] = [
    'asc' => ['catalog.ctitle' => SORT_ASC],
    'desc' => ['catalog.ctitle' => SORT_DESC],
];

// и только потом создаете сам провайдер данных
$dataProvider = new ActiveDataProvider([
    'query' => $query,
]);


т.е. изначально Вам нужно создать сам провайдер данных, и только потом для него задавать атрибуты сортировки. Сейчас же Вы делаете наоборот.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
slo_nik
@slo_nik Куратор тега Yii
Доброй ночи.
У Вас же нет в модели googs атрибута сatalog.ctitle?
Попробуйте так:
'attribute' => ctitle',
                'filter' => Catalog::find()
                                       ->select(['title', 'id']) // Ваши названия полей
                                       ->indexBy('id')
                                       ->column(),
                'value' => 'catalog.title' // Связь getCatalog(), я так понимаю надо вывести название, подставьте вместо title своё значение
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы