Как произвести сохранение связанных данных?

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Kven
Сообщения: 112
Зарегистрирован: 2016.10.20, 23:03

Как произвести сохранение связанных данных?

Сообщение Kven »

Всем здравствуйте! При сохранении данных связанных таблиц получаю следующую ошибку:

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

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'accept_id' cannot be null
The SQL being executed was: INSERT INTO `address` (`accept_id`, `city_id`, `street`, `house`, `name_building`, `floor`, `cabinet`) VALUES (NULL, 1, 'Дзержинского', '5', NULL, '1', 'б/н')
accept_id таблицы Address не может быть null

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

public function actionCreate()
{
    $model = new Accept();
    $address = new Address();
    $address->accept_id = $accept->id;

    if ($model->load(Yii::$app->request->post()) && $address->load(Yii::$app->request->post()) && $model->save()) {
        if ($address->save()) {
            $address->accept_id = $accept->id;
            return $this->redirect(['view', 'id' => $model->id]);
        }
    }
    return $this->render('create', compact('model', 'address'));
}
Я так понимаю, что ошибка у меня в контроллере, помогите пожалуйста разобраться с ошибкой. Документацией по сохранению связных данных пользовался.
Аватара пользователя
Alexum
Сообщения: 683
Зарегистрирован: 2016.09.26, 10:00

Re: Как произвести сохранение связанных данных?

Сообщение Alexum »

Можно начать с того, что вы расскажите про волшебный $accept->id и откуда оно берётся. Может там $model->id должен быть или во всём методе вместо $model должна использоваться переменная $accept. И тогда всё становится понятным, ибо сперва вы записываете туда id нового экземпляра Accept, и в этот момент он null (читай "В этом нет смысла, т.к. id модель получает только в момент сохранения в БД"). А затем обновляете его только после попытки сохранить address в БД.

PS. Сохранение связанных данных всегда лучше делать через транзакции, иначе есть риск поломать данные в БД при неудачном сохранении https://www.yiiframework.com/doc/guide/ ... operations
Kven
Сообщения: 112
Зарегистрирован: 2016.10.20, 23:03

Re: Как произвести сохранение связанных данных?

Сообщение Kven »

Спасибо! У меня в коде действительно было допущена такая глупая ошибка, там должно было быть $model->id. Подскажите, а как правильно тогда получить model->id, чтобы он все же сохранился в address->accept_id, как-то можно отловить момент сохранения id в таблицу accept ($model->id) и передать его в address->accept_id?
Аватара пользователя
Alexum
Сообщения: 683
Зарегистрирован: 2016.09.26, 10:00

Re: Как произвести сохранение связанных данных?

Сообщение Alexum »

Писал на коленках, но общий вид может быть таким:

PS. Это такой rapid-вариант, по хорошему контроллер должен быть намного тоньше а генерация ошибок и работа с транзакциями убрана в модели и хелперы.

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

public function actionCreate()
{
        $model = new Accept();
        $address = new Address();

        if ($model->load(Yii::$app->request->post()) && $address->load(Yii::$app->request->post()){
            $transaction = Yii::$app->db->beginTransaction();
            if($model->save()){
                $address->accept_id = $model->id;
                if($address->save()){
                    $transaction->commit();
                    return $this->redirect(['view', 'id' => $model->id]);
                } else {
		    $problemModel = $address;
                    $transaction->rollBack();
                }
            } else {
		$problemModel = $model;
            }
	    $errorsString = '';
            foreach ($problemModel->getErrors() as $key => $value) {
                $errorsString .= $key . ': ' . $value[0] . ',';
            }
            Yii::$app->getSession()->setFlash('error', $errorsString);
        }
        return $this->render('create', compact('model', 'address'));
    }
Ответить