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

В настоящее время я работаю над веб-приложением (написанным на 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) обязательно добавить любое количество отношений в модель, соединяясь с тем же полем БД, но в зависимости от условий,
2) и отобразить эти значения при включении сортировки по ним?

1

Решение

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

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

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

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

Затем я изменил имя параметра в массиве отношений, используемых с левым соединением. Это было главной проблемой в вашем коде. Вы использовали одно и то же имя для параметров, т.е. :product_price_field_id Я назначил другое имя для каждого параметра. Пока вы готовите 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

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]