2015-12-10 3 views
1

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

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

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

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

'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) и отображать эти значения ПОКА позволяет сортировать на их основе?

+0

разместить Ваш GridView код –

+0

@ChetanAmeta Я добавил данных столбцов из gridview. –

+0

Я заметил, что вы дважды проверяете цену с помощью 'empty()', а затем с '==" "'. Вам не нужно так поступать. Вы можете просто оставить 'empty()', это enougth: ''value' => '! Empty ($ data-> price2-> price)? $ data-> price2-> price: "-" '' – SiZE

ответ

2

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

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

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

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

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

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

Продукт.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); 
    } 
} 

GridView код

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

Вы можете нашли шаг за шагом руководство для поиска и сортировки по данным реляционных на Searching and sorting by related model in CGridView | Wiki | Yii PHP Framework

+0

Большое спасибо! Он отлично работает! –

+0

@AdamBenedek абсолютное удовольствие :) –

 Смежные вопросы

  • Нет связанных вопросов^_^