Yii2 связанные модели one to one


Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.

Ответить 54 сообщения codrilla Сообщения: 173 Зарегистрирован: 2013.03.06, 12:24 Откуда: Молдова, Тирасполь

Сохранение связанных моделей

  • Цитата
Никак не могу сделать сохранение связанных моделей. Ситуация такая:
В модели Car есть связь

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

public function getPhotos() { return $this->hasMany(Photo::className(), ['car_id' => 'id']); } Экшен создания Саr выглядит следующим образом

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

public function actionCreate() { if (Yii::$app->user->can('createCar')) { $model = new Car; //$modelPhoto = new Photo; if ($model->load(Yii::$app->request->post())) { $modelPhoto = new Photo; $images = UploadedFile::getInstances($modelPhoto, 'image'); foreach ($images as $image) { $modelPhoto = new Photo; $modelPhoto->image = $image; $model->link('photos', $modelPhoto); //вот эта строка не сработает, потому что ещё ни одна модель не сохранена //$model->photos[] = $modelPhoto так же не сработает (идея взята отсюда http://yiiframework.ru/doc/cookbook/ru/model.save.related.data). Выводится ошибка } if ($model->save()) { return $this->redirect(['view', 'id' => $model->id]); } } else { $modelPhoto = new Photo(); return $this->render( 'create', [ 'model' => $model, 'modelPhoto' => $modelPhoto ] ); } } else { throw new HttpException('403', Yii::t('app', 'У вас нет прав для публикации объявлений')); } } Ну и afterSave планирую сделать таким

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

public function afterSave($insert) { parent::afterSave($insert); foreach ($this->photos as $photo) { $photo->car_id = $this->id; $photo->save(); } } Подскажите, пожалуйста, как сделать это правильно. Заранее благодарен.

Вернуться к началу

Аватара пользователя mihail_dev Сообщения: 233 Зарегистрирован: 2013.07.17, 00:51 Откуда: Молдова Контактная информация: Контактная информация пользователя mihail_dev

Re: Сохранение связанных моделей

  • Цитата
если везде в остальном всё правильно то экшин должен по идее выглядеть примерно так

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

public function actionCreate() { if (Yii::$app->user->can('createCar')) { $model = new Car; $modelPhoto = new Photo; if ($model->load(Yii::$app->request->post())) { if ($model->save()) { $images = UploadedFile::getInstances($modelPhoto, 'image'); foreach ($images as $image) { $image->saveAs('some file name here'); $photo = new Photo; $photo->image = $image; $model->link('photos', $photo); } $this->redirect(['view', 'id' => $model->id]); } } return $this->render( 'create', [ 'model' => $model, 'modelPhoto' => $modelPhoto ] ); } else { throw new HttpException('403', Yii::t('app', 'У вас нет прав для публикации объявлений')); } }

Вернуться к началу

codrilla Сообщения: 173 Зарегистрирован: 2013.03.06, 12:24 Откуда: Молдова, Тирасполь

Re: Сохранение связанных моделей

  • Цитата

Да. Этот вариант действительно сработает. Просто ситуация такая, что связанные модели мне бы хотелось сохранять в afterSave основной модели, чтобы не дублировать потом тот же самый код в actionUpdate например, да и логически смотрится более правильно.

Вернуться к началу

codrilla Сообщения: 173 Зарегистрирован: 2013.03.06, 12:24 Откуда: Молдова, Тирасполь

Re: Сохранение связанных моделей

  • Цитата

И как я понял link использовать не получится, т.к. оригинальная модель Car ещё не сохранена и как следствие не имеет primary key. Не понятно, как избавиться от ошибки Indirect modification of overloaded property, когда делаю $model->photos[] = $modelPhoto

Вернуться к началу

codrilla Сообщения: 173 Зарегистрирован: 2013.03.06, 12:24 Откуда: Молдова, Тирасполь

Re: Сохранение связанных моделей

  • Цитата

Видимо придётся отказаться от afterSave в Car и делать link в контроллере. Неужели так и не появилось в yii2 сохранение связанных моделей?

Вернуться к началу

Аватара пользователя mihail_dev Сообщения: 233 Зарегистрирован: 2013.07.17, 00:51 Откуда: Молдова Контактная информация: Контактная информация пользователя mihail_dev

Re: Сохранение связанных моделей

  • Цитата

можно не отказываться просто в модель кар добавить публичную переменную с другим названием отличным от photos ну к примеру photosForSave
ошибка выдаётся так как у вас нет сеттера скорее всего в моделе кар а геттер у вас связь (public function getPhotos())

Вернуться к началу

codrilla Сообщения: 173 Зарегистрирован: 2013.03.06, 12:24 Откуда: Молдова, Тирасполь

Re: Сохранение связанных моделей

  • Цитата

Над этим вариантом тоже думал. А можно ли как-то задать сеттер для связи?

Вернуться к началу

zelenin Сообщения: 10170 Зарегистрирован: 2013.04.20, 11:30

Re: Сохранение связанных моделей

  • Цитата

codrilla писал(а):Да. Этот вариант действительно сработает. Просто ситуация такая, что связанные модели мне бы хотелось сохранять в afterSave основной модели, чтобы не дублировать потом тот же самый код в actionUpdate например, да и логически смотрится более правильно.

а разве link не сохраняет в БД?

Вернуться к началу

Аватара пользователя mihail_dev Сообщения: 233 Зарегистрирован: 2013.07.17, 00:51 Откуда: Молдова Контактная информация: Контактная информация пользователя mihail_dev

Re: Сохранение связанных моделей

  • Цитата
zelenin писал(а):

codrilla писал(а):Да. Этот вариант действительно сработает. Просто ситуация такая, что связанные модели мне бы хотелось сохранять в afterSave основной модели, чтобы не дублировать потом тот же самый код в actionUpdate например, да и логически смотрится более правильно.

а разве link не сохраняет в БД? link сохраняет модель которую связывает но не основную

Вернуться к началу

zelenin Сообщения: 10170 Зарегистрирован: 2013.04.20, 11:30

Re: Сохранение связанных моделей

  • Цитата
mihail_dev писал(а): zelenin писал(а):

codrilla писал(а):Да. Этот вариант действительно сработает. Просто ситуация такая, что связанные модели мне бы хотелось сохранять в afterSave основной модели, чтобы не дублировать потом тот же самый код в actionUpdate например, да и логически смотрится более правильно.

а разве link не сохраняет в БД? link сохраняет модель которую связывает но не основную ну так вы и сохраняете не основные

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

foreach ($this->photos as $photo) { $photo->car_id = $this->id; $photo->save(); }

Вернуться к началу

codrilla Сообщения: 173 Зарегистрирован: 2013.03.06, 12:24 Откуда: Молдова, Тирасполь

Re: Сохранение связанных моделей

  • Цитата

mihail_dev писал(а):public function setPhotos($value){
$this->some = $value;
}

И что такое в моём контексте $this->some?

Вернуться к началу

codrilla Сообщения: 173 Зарегистрирован: 2013.03.06, 12:24 Откуда: Молдова, Тирасполь

Re: Сохранение связанных моделей

  • Цитата

zelenin писал(а): ну так вы и сохраняете не основные

Такое сохранение в контроллере предложили позже. Я же изначально хотел сделать сохранение связанных моделей в afterSave

Вернуться к началу

codrilla Сообщения: 173 Зарегистрирован: 2013.03.06, 12:24 Откуда: Молдова, Тирасполь

Re: Сохранение связанных моделей

  • Цитата
Если кому-то интересно, в итоге сделал так:

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

/ Creates a new Car model. If creation is successful, the browser will be redirected to the 'view' page. @throws \yii\web\HttpException @return mixed / public function actionCreate() { if (Yii::$app->user->can('createCar')) { $model = new Car; $modelPhoto = new Photo; if ($model->load(Yii::$app->request->post()) && $model->save()) { $images = UploadedFile::getInstances($modelPhoto, 'image'); foreach ($images as $image) { $modelPhoto = new Photo; $modelPhoto->image = $image; $model->link('photos', $modelPhoto); } return $this->redirect(['view', 'id' => $model->id]); } else { $modelPhoto = new Photo(); return $this->render( 'create', [ 'model' => $model, 'modelPhoto' => $modelPhoto ] ); } } else { throw new HttpException('403', Yii::t('app', 'У вас нет прав для публикации объявлений')); } } / Updates an existing Car model. If update is successful, the browser will be redirected to the 'view' page. @param integer $id @throws \yii\web\HttpException @return mixed / public function actionUpdate($id) { $model = $this->findModel($id); if (Yii::$app->user->can('updateCar', ['car' => $model])) { $modelPhoto = new Photo; $modelsPhoto = $model->photos; if ($model->load(Yii::$app->request->post()) && $model->save()) { $images = UploadedFile::getInstances($modelPhoto, 'image'); foreach ($images as $image) { $modelPhoto = new Photo; $modelPhoto->image = $image; $model->link('photos', $modelPhoto); } return $this->redirect(['view', 'id' => $model->id]); } else { return $this->render( 'update', [ 'model' => $model, 'modelsPhoto' => $modelsPhoto, 'modelPhoto' => $modelPhoto ] ); } } else { throw new HttpException('403', Yii::t('app', 'У вас нет прав для редактирования данного объявления')); } }

Вернуться к началу

codrilla Сообщения: 173 Зарегистрирован: 2013.03.06, 12:24 Откуда: Молдова, Тирасполь

Re: Сохранение связанных моделей

  • Цитата

С сеттером для связи всё равно хотелось бы разобраться

Вернуться к началу

Аватара пользователя vova07 Сообщения: 1004 Зарегистрирован: 2012.11.29, 14:52 Откуда: Chisinau, Moldova

Re: Сохранение связанных моделей

  • Цитата

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

public function actionCreate() { if (Yii::$app->user->can('createCar')) { $model = new Car; $modelPhoto = new Photo; if ($model->load(Yii::$app->request->post())) { $images = UploadedFile::getInstances($modelPhoto, 'image'); $model->populateRelation('photos', $images); if ($model->save(false)) { return $this->redirect(['view', 'id' => $model->id]); } } else { $modelPhoto = new Photo(); return $this->render( 'create', [ 'model' => $model, 'modelPhoto' => $modelPhoto ] ); } } else { throw new HttpException('403', Yii::t('app', 'У вас нет прав для публикации объявлений')); } }

Свободный фриланс: http://find-freelancer.pro

Вернуться к началу

Аватара пользователя mihail_dev Сообщения: 233 Зарегистрирован: 2013.07.17, 00:51 Откуда: Молдова Контактная информация: Контактная информация пользователя mihail_dev

Re: Сохранение связанных моделей

  • Цитата
vova07 писал(а):

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

public function actionCreate() { if (Yii::$app->user->can('createCar')) { $model = new Car; $modelPhoto = new Photo; if ($model->load(Yii::$app->request->post())) { $images = UploadedFile::getInstances($modelPhoto, 'image'); $model->populateRelation('photos', $images); if ($model->save(false)) { return $this->redirect(['view', 'id' => $model->id]); } } else { $modelPhoto = new Photo(); return $this->render( 'create', [ 'model' => $model, 'modelPhoto' => $modelPhoto ] ); } } else { throw new HttpException('403', Yii::t('app', 'У вас нет прав для публикации объявлений')); } } а в самой моделе как обработать оно же автоматом не привяжет?

Вернуться к началу

Аватара пользователя vova07 Сообщения: 1004 Зарегистрирован: 2012.11.29, 14:52 Откуда: Chisinau, Moldova

Re: Сохранение связанных моделей

  • Цитата
Задача состояла в красивой передачи данных в модель. Код это решает.
А сохранение я обычно делаю в afterSave с включенными транзакциями для того чтобы сбросить все обратно в случае неудачи.

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

public function afterSave($insert) { parent::afterSave($insert); if ($this->photos !== null) { // Сохраняем наши связи } }

Свободный фриланс: http://find-freelancer.pro

Вернуться к началу

Аватара пользователя mihail_dev Сообщения: 233 Зарегистрирован: 2013.07.17, 00:51 Откуда: Молдова Контактная информация: Контактная информация пользователя mihail_dev

Re: Сохранение связанных моделей

  • Цитата
vova07 писал(а):Задача состояла в красивой передачи данных в модель. Код это решает.
А сохранение я обычно делаю в afterSave с включенными транзакциями для того чтобы сбросить все обратно в случае неудачи.

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

public function afterSave($insert) { parent::afterSave($insert); if ($this->photos !== null) { // Сохраняем наши связи } } да но если там уже есть фоты какие то над делать проверку связанно или нет или как?

Вернуться к началу

Аватара пользователя vova07 Сообщения: 1004 Зарегистрирован: 2012.11.29, 14:52 Откуда: Chisinau, Moldova

Re: Сохранение связанных моделей

  • Цитата

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

Свободный фриланс: http://find-freelancer.pro

Вернуться к началу

Создано на основе phpBB® Forum Software © phpBB Limited
Русская поддержка phpBB
GZIP: Off

 


Источник: http://www.yiiframework.ru/forum/viewtopic.php?t=18415



Рекомендуем посмотреть ещё:


Закрыть ... [X]

Сохранение связанных моделей - Yii Framework Поэтапно роспись стен

Yii2 связанные модели one to one Yii2 связанные модели one to one Yii2 связанные модели one to one Yii2 связанные модели one to one Yii2 связанные модели one to one Yii2 связанные модели one to one Yii2 связанные модели one to one Yii2 связанные модели one to one

ШОКИРУЮЩИЕ НОВОСТИ