relations в модели

И снова добрый день.

Помогите пожалуйста разобраться с relations в моделях и использовании в дальнейшем в гриде.

Есть таблица (для примера):


CREATE TABLE links(

id int not null auto_increment,

id_link int not null default '0', # поле замыкается на другом поле в этой же таблице

name varchar(20) not null,

 PRIMARY KEY (id)

);

Собственно что требуется, вывести в гриде данные из этой таблицы, и если id_link != 0, то соответственно вместо него выводить name родительского линка.

Никак не могу понять чего и где использовать, вроде как такое должно быть:

В модели:


    public function relations()

    {

        return array(

          'link_name' => array(self::HAS_ONE, 'Links', 'id'),

        );

    }



В контроллере:


$dataProvider = Direction::model()->with('link_name')->search();

В вьюхе:




  $this->beginWidget('ext.mygrid.VGrid', array(

    'dataProvider'=>$dataProvider,

    'columns'=>array(

      'id',

      'link_name.name',

      'name',

    ),

  ));

  $this->endWidget();




Но четта выводит само себя…

relations() неверный. Нужен такой:




    public function relations()

    {

        return array(

          'link' => array(self::BELONGS_TO, 'Links', 'id_link'),

        );

    }



И еще не понятно, почему в relations() второй аргумент - Links, а в контроллере модель уже Direction. Вы же сказали, что таблица связана сама с собой? Значит должно быть что-то вроде:




Links::model()->with('link')->findAll();



Спасибо за ответ. Я тут уже по уши закопанный в relations… Похоже проблема несколько глубже, никак в документации понять не могу как делать связки. О_о

Пробую пока еще раз перепробовывать все примеры из форума и того что гугл показал, но всеравно пока туплю в логику построения отношений.

Прошу прощения, в контроллере случайно написал Direction, я просто упростил таблицу для примера до трех полей, рабочая таблица иная и там куча полей. Конечно же в контролере:




$dataProvider = Links::model()->with('link_name')->search();



Ой, кажись, получилось… благодаря BELONGS_TO. Но в любом случае еще пока не понимаю как оно "функциклирует".

Итоговое (для тех кто с тем же вопросом прийдет), стало нечто типа такого:

В модели:




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(

          'linkRelationName' => array(self::BELONGS_TO, 'Links', 'id_link'),

        );

    }



В контроллере:


$dataProvider = Links::model()->with('linkRelationName')->search();

В вьюхе:




  $this->beginWidget('ext.mygrid.VGrid', array(

    'dataProvider'=>$dataProvider,

    'columns'=>array(

      'id',

      array(

        'header'=>'Родительское',

        'name'=>'linkRelationName.name'

      ),

      'name',

    ),

  ));

  $this->endWidget();



Чувствую что бред какой-то, но вроде работает… О_о

Всё верно. Вы можете не понимать логику работы по двум причинам:

  1. Не понимаете, как работают JOIN’ы в SQL.

  2. Не прочитали мануал N раз (N зависит от человека :) ).

Если коротко объяснять, то:

  1. BELONGS_TO, потому что это связь многие-к-одному, т.к. элементов с аналогичным id_link может быть много.

  2. Третий элемент массива всегда внешний ключ. В первом варианте у вас был первичный ключ, и таблица соединялась сама с собой по нему, а не по id_link, как надо.

По-большей части не могу въехать из-за того что в голове каша + сроки жмут, никогда не использовал фреймворки, а тут просто захотелось чего-то новенького и экстремального.

Включи CWebLogRoute, и смотри какие запросы строит yii, я лично так разбирался…