Получение данных для нескольких моделей

Имея дело с некоторыми сложными данными, возможно, вам может понадобиться использовать несколько разных моделей для сбора пользовательского ввода. Например, предполагая, что информация о пользователе хранится в таблице user, а информация о профиле пользователя хранится в таблице profile, вы можете захотеть собрать входные данные о пользователе через модель User и модель Profile. С поддержкой модели и форм Yii эту проблему можно решить так, чтобы она не сильно отличалась от обработки одной модели. Далее мы покажем, как вы можете создать форму, которая позволит вам собирать данные для моделей User и Profile.

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

namespace app\controllers;

use Yii;
use yii\base\Model;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use app\models\User;
use app\models\Profile;

class UserController extends Controller
{
    public function actionUpdate($id)
    {
        $user = User::findOne($id);
        if (!$user) {
            throw new NotFoundHttpException("The user was not found.");
        }
        
        $profile = Profile::findOne($user->profile_id);
        
        if (!$profile) {
            throw new NotFoundHttpException("The user has no profile.");
        }
        
        $user->scenario = 'update';
        $profile->scenario = 'update';
        
        if ($user->load(Yii::$app->request->post()) && $profile->load(Yii::$app->request->post())) {
            $isValid = $user->validate();
            $isValid = $profile->validate() && $isValid;
            if ($isValid) {
                $user->save(false);
                $profile->save(false);
                return $this->redirect(['user/view', 'id' => $id]);
            }
        }
        
        return $this->render('update', [
            'user' => $user,
            'profile' => $profile,
        ]);
    }
}

В действии update мы сначала загружаем модели $user и $profile для обновления из базы данных. Затем мы вызываем yii\base\Model::load() для заполнения этих двух моделей пользовательским вводом. Если загрузка будет успешной, мы проверим две модели и затем сохраним их - обратите внимание, что мы используем save (false), чтобы пропускать проверки в моделях, поскольку пользовательские входные данные уже были проверены. Если загрузка не будет успешной, мы отобразим представление update, которое имеет следующий контент:

<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;

$form = ActiveForm::begin([
    'id' => 'user-update-form',
    'options' => ['class' => 'form-horizontal'],
]) ?>
    <?= $form->field($user, 'username') ?>

    ...other input fields...
    
    <?= $form->field($profile, 'website') ?>

    <?= Html::submitButton('Update', ['class' => 'btn btn-primary']) ?>
<?php ActiveForm::end() ?>

Как вы можете видеть, в представлении update вы визуализировали поля ввода с использованием двух моделей: $user и $profile.