сохранение many_many

никак не работает сохранение с отношением многие-ко-многим.

преамбула: есть такие таблицы


CREATE TABLE `employees` (

  `id` int(10) unsigned NOT NULL auto_increment,

  `first_name` varchar(255) collate utf8_unicode_ci NOT NULL,

  `last_name` varchar(255) collate utf8_unicode_ci NOT NULL,

  PRIMARY KEY  (`id`)

)




CREATE TABLE `employees_professions` (

  `employee_id` int(10) unsigned NOT NULL,

  `profession_id` smallint(5) unsigned NOT NULL,

  PRIMARY KEY  (`employee_id`,`profession_id`),

  KEY `FK_professions_employees` (`profession_id`),

  CONSTRAINT `FK_professions_employees` FOREIGN KEY (`profession_id`) REFERENCES `professions` (`id`) ON DELETE CASCADE,

  CONSTRAINT `FK_employees_professions` FOREIGN KEY (`employee_id`) REFERENCES `employees` (`id`) ON DELETE CASCADE

)




CREATE TABLE `professions` (

  `id` smallint(5) unsigned NOT NULL auto_increment,

  `title` varchar(255) collate utf8_unicode_ci NOT NULL,

  PRIMARY KEY  (`id`),

  UNIQUE KEY `title` (`title`)

)

есть модель Employees c отношениями:




public function relations() {

   return array(

      'professions' => array(self::MANY_MANY, 'Professions', 'employees_professions(employee_id, profession_id)'),

   );

}

есть модель Professions с таким же отношением:




public function relations() {

   return array(

      'employees' => array(self::MANY_MANY, 'Employees', 'employees_professions(employee_id, profession_id'),

   );

}

во форме модели Employee добавляю поле




CHtml::activeDropDownList($model, 'professions', CHtml::listData(Professions::model()->findAll(), 'id', 'title'), array('multiple' => 'multiple'));



список выводится отличный, но при сохранении


$model->attributes = $_POST['Employees'];

$model->attributes не содержит professions. Поле professions указано в safeAttributes. В чем может быть проблема?

И не должно.


$model->attributes

формируется из данных полученных от ФОРМЫ через Post. Если ты распечатаешь сам суперглобал массив пост то увидишь что там такого тоже нету. И это естественно, т.к. связи не сохраняются при передаче через формы, да и вобще некакого отнашения к ним не имеют. Согласно твоему "activeDropDownList" в post будут переданы только id-шники. А вот дальше если тебе из айдишников надо получить связь "professions" то делаешь все ручками.

п.с. разве с ходу не понятно что весьма накладно (и не безопасно) было бы для трафика юзеров передавать через форму все связи твоих моделей?!.

ну, кагбэ есть




Array

(

    [last_name] => last_name

    [first_name] => first_name

    [professions] => Array

        (

            [0] => 4

            [1] => 2

        )


)



еще идеи?

вот это не совсем понял, что я там небезопасного передаю?

Ты привел принтовку $_POST в экшинсе на которой уходит запрос от формы?

Что то оно не особо в том формате в котором надо как по мне.

а принтани еще атрибутес.

это $_POST[‘Employees’], в атрибутах это же, за исключением professions… было, сейчас работает нормально. магия, не иначе.

тогда второй вопрос, как мне в dropdown-списке при редактировании выделить назначенные профессии? я думал, они автоматом выделятся, но что-то не работает… или все-таки ручками надо?

Последний парраметр там htmlOptions, в него и передаете в виде массива:

"номер_элемент" => "checked". так для всех которые надо что б были выбраны в списке. естественно сам массив выбранных строится вами и просто туда передается.

это я знаю, только не "checked" там, а "selected", но да и не суть. так и сделал сразу, но вопрос в том, что почему для обычного выпадающего списка автоматически выставляется его сохраненное значение, а здесь - нет? это так и задумано или просто я как-то криво связи обозначил или еще где слажал?

В смысле автоматически выставляются? А от какого поля в базе вы отталкиваетесь что надо выставить значение "selected" ?

отталкиваюсь от опыта разработки на кейке: там не нужно даже элементы скармливать, а просто указать в атрибутах инпута название отношения, а дальше он сам разбирается - и генерирует сам, и выделяет тоже сам

Ну так что б самому что то выделить - вы должны либо отдать их в activeDropDownList что бы он понял что их надо выделять, либо иметь некое правило по которому собираетесь сделать выделение элементов. К примеру все чётные записи, или все записи с атрибутом "true" в колонке "deleted". У вас по какому принципу должны выделяться записи?

ну по какому же еще? наверное те, которые были выбраны при создании.

вопрос закрыт, как удалось выяснить, без массива ‘options’ здесь не обойтись.