yii - сохранение связки типа MANY_MANY (many to many) - пример сохранения и вывода табличной обработки данных связанных моделей
Primary tabs
вроде как стандартных средств для разруливания подобных "сложных" отношений в Yii нет, а потому предлагается использовать это расширение
-и ещё - по слухам надо указать, в правилах валидации, что отношение безопасно, например ,для categories,это выглядит как-то так:
public function rules() { return array( array('categories', 'safe'), ); }
Расширение ESaveRelatedBehavior
Опять вернёмся к расширению, которое мы собрались использовать - вообще-то о том как это делать уже написано здесь
Далее качаем архив - в моё (на странице он справа - берите последнюю версию) - название файла будет вроде:
ESaveRelatedBehavior-v1.5.zip
ну и в модели, в которой собираемся использовать это прекрасное расширение напишем "публичный" метод:
// необходимо для использования расширения ESaveRelatedBehavior // которое позвляет созранять отношения типа MANY_MANY public function behaviors() { return array('ESaveRelatedBehavior' => array( 'class' => 'application.components.ESaveRelatedBehavior') ); }
затем нам стоит вспомнить про обработку табличного ввода (рассмотрим ситуацию, когда к странице привязана целая туча человек - и вот их мы будем выводить в виде таблицы - например страница - это конференция + массив сущностей "участник конференции" - но при этом нам надо организовать на одной странице как редактирование самой странице(информация о конференции) - так и списка участников - их как минимум, надо уметь добавлять)
Сохранение связанной('привязанной') сущности из формы
Пусть в модели страницы, связь с участниками определена следующим образом:
public function relations() // задаём отношения с другими классами { return array( // связи 'persons' => array(self::MANY_MANY, 'Person', 'page_person(page_id, person_id)'), ); }
тогда вывести поле для имени одного из участников(пусть первого в списке) можно так:
<?php echo CHtml::activeTextField($model,'persons[1][info]'); ?>
то есть мы просто как бы говорим yii по средством html что будем использовать массив -
далее при сохранении модели страницы - мы можем проверить что хотя бы один из элементов массива определён и сохранить
экземпляры моделей всех привязанных к данной странице участников - при этом одновременно заполним таблицу отношения многие-ко многим.
У меня нет времени особенно вдаваться в возможности модуля - так как это моё первое рабочее приложение на Yii, а потому я предлагаю вам, друзья, такой вот пример обхода массива связанных сущностей ,который мы концептуально рассматриваем как одно из полей основной модели -
привожу фрагмент кода действия editPage :
function actionEditPage($id) // получаем через GET id редактируемой страницы { // сначала проверка прав доступа if (!Yii::app()->user->checkAccess('updatePost')) { throw new CHttpException(403, 'Forbidden'); } // подгружаем модель по id // подгрузку модели в принципе можно заменить // созданием новой $page = Page::model()->with('persons')->findByPk($id); // если не нашли по id if (!$page) throw new Exception('Bad id.'); // если форма отправлена if (isset($_POST['Page'])) { // если данные из формы пришли $page->attributes = $_POST['Page']; // сохраняем модель $persons = array(); // сюда будем созранять индексы имеющихся моделей if ($_POST['Page']['persons']){ // проверяем что хоть что-то пришло // раз пришло -начинаем "обходить" массив foreach ($_POST['Page']['persons'] as $key => $value) { $person = new Person(); $person->attributes = $value; $person->save(); $persons[] = $person->id; // собираем id-шники созранённых моделей в массив Yii::trace("добавляем персону ))", 'info' ); // просто трассировка } $page->persons = $persons;// сохраняем сведения о номерах связанных сущностей } if ($page->validate()) // проыеряем форму (да проверку вообще надо раньше делать) $page->saveWithRelated('persons'); // ВОТ ОНО! сохраняем данные в доп. талблицу // для разруливания MANY_MANY $this->redirect(array('perfomance/pageslist')); // переходим к списку страниц } // если данные от формы не отправлены - $this->render('editpage', array('model' => $page)); // То просто выводим форму редактирования }
при этом следует помнить что вызов ->saveWithRelated('persons') - затрёт в таблице все старые элементы привязанные к данной странице и добавит новые - чтобы старые элементы не стирались надо написать вызов обновления в виде:
$model->saveWithRelated( array('relationName1' => array('append' => true)));
append = 'прилагать, добавлять'. То есть в для приведённого выше примера можно было бы написать:
$page->saveWithRelated( array('persons' => array('append' => true)));
вот так-то )))
- Log in to post comments
- 9225 reads