CGridView и AR relations

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
Аватара пользователя
alexzv
Сообщения: 120
Зарегистрирован: 2010.04.23, 00:10
Откуда: Украина, Киев

CGridView и AR relations

Сообщение alexzv »

Не могу разобраться, что я делаю не так. Есть 2 таблицы `Good` и `Category`, так же соответствующие имена моделей. В `Good` я добавил foreign key:

Код: Выделить всё

ALTER TABLE `Good`
  ADD CONSTRAINT `Good_fk_category` FOREIGN KEY (`category_id`) REFERENCES `Category` (`id`);
В моделе Good описываю relations:

Код: Выделить всё

public function relations()
{
  return array(
    'category'=>array(self::BELONGS_TO, 'Category', 'Good_fk_category'),
  );
}
 
dataProvider получаем так:

Код: Выделить всё

public function searchAdmin()
{
  $criteria=new CDbCriteria;
  $criteria->compare('id',$this->id);
  $criteria->compare('developer',$this->developer,true);
  $criteria->compare('series',$this->series,true);
  $criteria->compare('model',$this->model,true);
  $criteria->compare('modelfull',$this->modelfull,true);
  $criteria->compare('name',$this->name,true);
  $criteria->compare('category_id',$this->category_id);
  $criteria->compare('shop_id',$this->shop_id);
  $criteria->compare('available',$this->available);
  $criteria->compare('special',$this->special);
  $criteria->compare('created',$this->created,true);
  $criteria->with = array('Category');

  return new CActiveDataProvider(get_class($this), array(
    'criteria'=>$criteria,
  ));
}
 
потом пытаюсь вывести список элементов модели Good с помощью CGridView:

Код: Выделить всё

$this->widget('zii.widgets.grid.CGridView', array(
  'id'=>'good-grid',
  'dataProvider'=>$dataProvider,
  'filter'=>$model,
  'columns'=>array(
    'id',
    array(
      'name'=>'category_id',
      'filter'=>$category_list,
      'value'=>'$model->category->name',
    ),
    'name',
    array(
      'name'=>'shop_id',
      'filter'=>$shop_list,
    ),
    array(
      'class'=>'CButtonColumn',
    ),
  ),
));
 
на что мне сообщает:

Код: Выделить всё

Отношение "Category" не было определено в active record классе "Good". 
пробовал так же в relations указывать вместо 'Good_fk_category' поле 'category_id', ничего не получается... Что-то я явно упустил...
Аватара пользователя
TrustNik
Сообщения: 65
Зарегистрирован: 2009.10.25, 14:21
Откуда: Воронеж

Re: CGridView и AR relations

Сообщение TrustNik »

Попробуй так:
В GridView вместо:

Код: Выделить всё

 array(
      'name'=>'category_id',
      'filter'=>$category_list,
      'value'=>'$model->category->name',
    ), 
Вот это:

Код: Выделить всё

 array(
     'class' => 'CDataColumn',
      'name'=>'category.name',
    ),
 
filter задать не получится насколько я понял заглянув в ядро. (Или я ошибаюсь?)
value тебе при таком варианте не нужен.
Аватара пользователя
alexzv
Сообщения: 120
Зарегистрирован: 2010.04.23, 00:10
Откуда: Украина, Киев

Re: CGridView и AR relations

Сообщение alexzv »

Разобрался, основная проблема была в dataProvider, а именно строка $criteria->with = array('Category'); - название relations у меня с маленькой буквы, т.е. $criteria->with = array('category');

Так же в relations необходимо указывать имя поля 'category_id', т.е. то же, что и имя реального поля в БД (а не имя ключа, как я вначале подумал).

А в CGridView работает такой вариант

Код: Выделить всё

array(
      'name'=>'category_id',
      'filter'=>$category_list,
      'value'=>'$data->category->name',
    ), 
 
только остались вопросы - почему именно "$data"? Оно та работает, теперь вместо id сатегории выводится ее имя... А как можно более простые варианты выводить? Например поле `available` - оно может быть только "1" и "0", т.е. "Есть в наличии" и "Нет в наличии", можно ли это как-то выводить?
Аватара пользователя
TrustNik
Сообщения: 65
Зарегистрирован: 2009.10.25, 14:21
Откуда: Воронеж

Re: CGridView и AR relations

Сообщение TrustNik »

alexzv писал(а):только остались вопросы - почему именно "$data"?
Зарезервированное слово, см. Api.
alexzv писал(а): Оно та работает, теперь вместо id сатегории выводится ее имя...
Правильно, при указании value, то что пишешь в name игнорируется.
Укажи так:

Код: Выделить всё

'value' => '$data->category->id'
 
alexzv писал(а): А как можно более простые варианты выводить? Например поле `available` - оно может быть только "1" и "0", т.е. "Есть в наличии" и "Нет в наличии", можно ли это как-то выводить?
Вот у меня "булевское" поле:

Код: Выделить всё

array(
                'class' => 'CDataColumn',
                'name' => 'active',
                'value' => '$data->active == 1 ? "Да" : "Нет"',
                'filter' => array(1 => 'Да', 0 => 'Нет'),
            ), 
Аватара пользователя
alexzv
Сообщения: 120
Зарегистрирован: 2010.04.23, 00:10
Откуда: Украина, Киев

Re: CGridView и AR relations

Сообщение alexzv »

Насчет имени категории это понятно ;-) А вот за остальное спасибо, теперь все понятно. Насколько я понял, то в 'value' можно функцию вызывать, передавая ей значение $data и в качестве значения поля будет выводиться результат работы функции... Я так понимаю что 'value' обрабатывается с помощью eval(), тогда все на свои места стает! :-)
Аватара пользователя
TrustNik
Сообщения: 65
Зарегистрирован: 2009.10.25, 14:21
Откуда: Воронеж

Re: CGridView и AR relations

Сообщение TrustNik »

Ответить