Столбец CGridView на основе отношения отображает неверные данные

1

В настоящее время я работаю над веб-приложением (написанным на PHP, основанным на Yii), которое, среди прочего, позволяет вам устанавливать разные цены для продуктов. Каждый продукт может иметь несколько цен, но система построена таким образом, что я могу легко (и правильно) определить тип ценового поля - так что, в то время как каждый продукт может иметь несколько полей цены, он может иметь только один тип каждого типа ценовые поля.

Часть, в которой я застряла, - это когда я должен отображать сохраненное значение этих полей в списке и заказывать их по списку - я могу правильно их отобразить и отсортировать по одному столбцу, но как только я попытаюсь сделать список сортируется по всем столбцам (не в то же время, конечно), строки начинают отображать неправильные значения.

Вот соответствующие фрагменты кода:

В модели, при отношениях:

'productPriceConnects' => array(Product::HAS_MANY, 'ProductPriceConnect', 'product_id'),
'price1' => array(Product::HAS_ONE, 'ProductPriceConnect', 'product_id',
    'joinType' => 'LEFT JOIN',
    'on' => 'priceBeszerzesi.product_price_field_id=:product_price_field_id AND priceBeszerzesi.active = 1',
    'params' => array(':product_price_field_id' =>ProductPriceField::model()->findByAttributes(array('active' => 1, 'type' => 1, 'category' => 6))->id),
    'alias' => 'priceBeszerzesi',
),
'price2' => array(Product::HAS_ONE, 'ProductPriceConnect', 'product_id',
    'joinType' => 'LEFT JOIN',
    'on' => 'priceEladasi.product_price_field_id=:product_price_field_id AND priceEladasi.active = 1',
    'params' => array(':product_price_field_id' => ProductPriceField::model()->findByAttributes(array('active' => 1, 'type' => 1, 'category' => 1))->id),
    'alias' => 'priceEladasi'
),
'price3' => array(Product::HAS_ONE, 'ProductPriceConnect', 'product_id',
    'joinType' => 'LEFT JOIN',
    'on' => 'priceAkcios.product_price_field_id=:product_price_field_id AND priceAkcios.active = 1',
    'params' => array(':product_price_field_id' => ProductPriceField::model()->findByAttributes(array('active' => 1, 'type' => 1, 'category' => 5))->id),
    'alias' => 'priceAkcios'
),

В модели, при поиске:

...
$criteria->with('price1', 'price2', 'price3);

...

$criteria->compare('price1.price', $this->beszerzesi, true);
$criteria->compare('price2.price', $this->eladasi, true);
$criteria->compare('price3.price', $this->akcios, true);

...
$sort->attributes = array(
    'price1' =>array(
        'asc' => 'priceBeszerzesi.price ASC',
        'desc' => 'priceBeszerzesi.price DESC',
    ),
    'price2' =>array(
        'asc' => 'priceEladasi.price ASC',
        'desc' => 'priceEladasi.price DESC',
    ),
    'priceAkcios' =>array(
        'asc' => 'price3.price ASC',
        'desc' => 'price3.price DESC',
    ),
    '*'
);

...

return new CActiveDataProvider($this, array(
        'criteria' => $criteria,
        'sort' => $sort,
        'pagination' => array(
            'pageSize' => 10,
        ),
    )
);

Данные столбцов в gridview:

'eladasi' => array(
    'name' => 'price2',
    'header' => 'Eladási ár',
    'type' => 'raw',
    'headerHtmlOptions' => array('class' => 'auto-width text-center'),
    'value' => '!empty($data->price2->price) ? $data->price2->price == "" ? "-" : $data->price2->price : "-"',
    'htmlOptions' => array('class' => 'border-right auto-width text-center'),
),
'akcios' => array(
    'name' => 'priceAkcios',
    'header' => 'Akciós',
    'value' => '!empty($data->price3->price) ? $data->price3->price == "" ? "-" : $data->price3->price : "-"',
    'headerHtmlOptions' => array('class' => 'auto-width text-center'),
    'htmlOptions' => array('class' => 'border-right auto-width text-center'),
),
    'beszerzesi' => array(
    'name' => 'price1',
    'header' => 'Beszerzési ár',
    'type' => 'raw',
    'value' => '!empty($data->price1->price) ? $data->price1->price == "" ? "-" : $data->price1->price : "-"',
    'headerHtmlOptions' => array('class' => 'auto-width text-center'),
    'htmlOptions' => array('class' => 'border-right auto-width text-center'),
),

Этот код позволяет сортировать список по всем трем реляционным зависимым столбцам, но каждый столбец отображает то же значение - значение последнего соотношения в with массивом. Если последний элемент в массиве - price3, то столбцы отображают значение отношения price3. Когда я удаляю все имена отношений из массива with ожиданием, я могу отсортировать список по этому столбцу, но не другие.

Мой вопрос заключается в следующем: есть ли способ 1) уверенно добавить любое количество отношений к модели, подключаясь к одному и тому же поле db, но в зависимости от условий, 2) и отображать эти значения WHILE, позволяющие сортировать на их основе?

  • 0
    опубликуйте свой код gridview
  • 0
    @ChetanAmeta Я добавил данные столбцов из сетки.
Показать ещё 3 комментария
Теги:
yii
gridview-sorting

1 ответ

2
Лучший ответ

Найдите решение ниже:

Я создал эти таблицы в своей системе и использовал ваше отношение и код gridview. Я внесла некоторые изменения в этот код, и теперь ниже поиск и сортировка кода работают отлично.

Я определил три переменные в классе модели, т.е.

public $beszerzesi;
public $eladasi;
public $akcios;

Затем я изменил имя параметра в отношении arraye, используемое с левым соединением. Это было основной проблемой в вашем коде. Вы использовали то же имя для параметров, то есть :product_price_field_id Я назначил другое имя для каждого параметра. В то время как yii готовит sql-запрос, он заменит параметры, назначенные запросу. В вашем случае он заменял одинаковое значение для всех трех параметров.

Также я внес некоторые изменения в атрибуты сортировки и сравнения, переданные в CActiveDataProvider. Вы можете найти все изменения ниже файла модели.

product.php

<?php

/**
 * This is the model class for table "product".
 *
 * The followings are the available columns in table 'product':
 * @property integer $id
 * @property string $name
 */
class Product extends CActiveRecord
{
    public $beszerzesi;
    public $eladasi;
    public $akcios;

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'product';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('name', 'required'),
            array('name', 'length', 'max' => 100),
            // The following rule is used by search().
            // @todo Please remove those attributes that should not be searched.
            array('id, name, beszerzesi, eladasi,akcios', 'safe', 'on' => 'search'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
            'productPriceConnects' => array(Product::HAS_MANY, 'ProductPriceConnect', 'product_id'),
            'price1' => array(Product::HAS_ONE, 'ProductPriceConnect', 'product_id',
                'joinType' => 'LEFT JOIN',
                'on' => 'priceBeszerzesi.product_price_field_id=:product_price_field_id1 AND priceBeszerzesi.active = 1',
                'params' => array(':product_price_field_id1' => ProductPriceField::model()->findByAttributes(array('active' => 1, 'type' => 1, 'category' => 6))->id),
                'alias' => 'priceBeszerzesi',
            ),
            'price2' => array(Product::HAS_ONE, 'ProductPriceConnect', 'product_id',
                'joinType' => 'LEFT JOIN',
                'on' => 'priceEladasi.product_price_field_id=:product_price_field_id2 AND priceEladasi.active = 1',
                'params' => array(':product_price_field_id2' => ProductPriceField::model()->findByAttributes(array('active' => 1, 'type' => 1, 'category' => 1))->id),
                'alias' => 'priceEladasi'
            ),
            'price3' => array(Product::HAS_ONE, 'ProductPriceConnect', 'product_id',
                'joinType' => 'LEFT JOIN',
                'on' => 'priceAkcios.product_price_field_id=:product_price_field_id3 AND priceAkcios.active = 1',
                'params' => array(':product_price_field_id3' => ProductPriceField::model()->findByAttributes(array('active' => 1, 'type' => 1, 'category' => 5))->id),
                'alias' => 'priceAkcios'
            ),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => 'ID',
            'name' => 'Name',
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     *
     * Typical usecase:
     * - Initialize the model fields with values from filter form.
     * - Execute this method to get CActiveDataProvider instance which will filter
     * models according to data in model fields.
     * - Pass data provider to CGridView, CListView or any similar widget.
     *
     * @return CActiveDataProvider the data provider that can return the models
     * based on the search/filter conditions.
     */
    public function search()
    {
        // @todo Please modify the following code to remove attributes that should not be searched.

        $criteria = new CDbCriteria;

        $criteria->with = array('price1', 'price2', 'price3');

        $criteria->compare('id', $this->id);
        $criteria->compare('name', $this->name, true);

        $criteria->compare('priceBeszerzesi.price', $this->beszerzesi, true);
        $criteria->compare('priceEladasi.price', $this->eladasi, true);
        $criteria->compare('priceAkcios.price', $this->akcios, true);

//        $criteria->attributes = ;

        return new CActiveDataProvider($this, array(
                'criteria' => $criteria,
                'sort' => array(
                    'attributes' => array(
                        'beszerzesi' => array(
                            'asc' => 'priceBeszerzesi.price',
                            'desc' => 'priceBeszerzesi.price DESC',
                        ),
                        'eladasi' => array(
                            'asc' => 'priceEladasi.price',
                            'desc' => 'priceEladasi.price DESC',
                        ),
                        'akcios' => array(
                            'asc' => 'priceAkcios.price',
                            'desc' => 'priceAkcios.price DESC',
                        ),
                        '*'
                    )
                ),
                'pagination' => array(
                    'pageSize' => 10,
                ),
            )
        );
    }

    /**
     * Returns the static model of the specified AR class.
     * Please note that you should have this exact method in all your CActiveRecord descendants!
     * @param string $className active record class name.
     * @return Product the static model class
     */
    public static function model($className = __CLASS__)
    {
        return parent::model($className);
    }
}

код сетки

<?php $this->widget('zii.widgets.grid.CGridView', array(
    'id' => 'product-grid',
    'dataProvider' => $model->search(),
    'filter' => $model,
    'columns' => array(
        'id',
        'name',
        'eladasi' => array(
            'name' => 'eladasi',
            'header' => 'Eladási ár',
            'type' => 'raw',
            'headerHtmlOptions' => array('class' => 'auto-width text-center'),
            'value' => '!empty($data->price2->price) ? $data->price2->price == "" ? "-" : $data->price2->price : "-"',
            'htmlOptions' => array('class' => 'border-right auto-width text-center'),
        ),
        'akcios' => array(
            'name' => 'akcios',
            'header' => 'Akciós',
            'value' => '!empty($data->price3->price) ? $data->price3->price == "" ? "-" : $data->price3->price : "-"',
            'headerHtmlOptions' => array('class' => 'auto-width text-center'),
            'htmlOptions' => array('class' => 'border-right auto-width text-center'),
        ),
        'beszerzesi' => array(
            'name' => 'beszerzesi',
            'header' => 'Beszerzési ár',
            'type' => 'raw',
            'value' => '!empty($data->price1->price) ? $data->price1->price == "" ? "-" : $data->price1->price : "-"',
            'headerHtmlOptions' => array('class' => 'auto-width text-center'),
            'htmlOptions' => array('class' => 'border-right auto-width text-center'),
        ),
        array(
            'class' => 'CButtonColumn',
        ),
    ),
)); ?>

Вы можете найти пошаговое руководство для поиска и сортировки данных отношений при поиске и сортировке по соответствующей модели в CGridView | Вики | Yii PHP Framework

  • 0
    Большое спасибо! Работает отлично!
  • 0
    @AdamBenedek абсолютное удовольствие :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню