Как сохранить значения нескольких радиостанций в yii2 activeForm?

У меня есть приложение для проведения опросов со многими вопросами. Каждый вопрос имеет варианты, которые представлены в виде радиолиста. Я использую ActiveForm и RadioList в цикле for, чтобы получить все вопросы и варианты из базы данных. Все в порядке с печатью вопросов и вариантов, но

Когда я пытаюсь сохранить ответы в базу данных, она сохраняет только последний вариант.

В своем действии сохранения я попытался создать цикл foreach, чтобы сохранить каждый ответ, но у меня это не сработало.

Я попытался var_dump $model->save и $request->post('Questions'), там есть все выбранные варианты, а не только последний.

Модель: здесь только правила:

public function rules(){
  return[
    [['id','question_id',  'option_id'], 'required']
  ];

}

Просмотр:

<?php $form = ActiveForm::begin([
    'id' => 'my-form-id',
    'action' => ['answers/save'],
]
); 

?> 

<?php $questions = Questions::find()->orderBy('id ASC')->all(); ?>

  <?php for ($i=0; $i<count($questions); $i++): ?>    
     <?= Html::encode("{$questions[$i]->title}") ?>
  <?php $options = Options::find()->where (['question_id'=>$questions[$i]->id])->orderBy('id ASC')->all();
  $options = ArrayHelper::map($options,'id', 'title');
  ?>
  <label class="container" >
    <?= $form->field($model, 'option_title')->radioList(
        $options, 
        ['name'=>'Questions['.$questions[$i]->id.']', 
        'separator' => '<br>',
        ])->label(false) ?>        
  </label>

<?php endfor; ?>

<?= Html::submitButton('Save', ['class' => 'btn btn-primary']) ?>

<?php ActiveForm::end(); ?>

Контроллер:

public function actionSave(){        
  $model = new Answers();
  $request = \Yii::$app->request;
  foreach($request->post('Questions') as $key=>$value) {
    $model->load($request->post());
    $model->option_id = $value;
    $model->question_id = $key;
    $model->save();
  }
}

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


person Mirzhana Maxutova    schedule 16.07.2019    source источник


Ответы (1)


Вам нужно переместить $model = new Answers(); внутри цикла, так как вам нужно сохранить все флажки, зациклив массив сообщений, вы должны каждый раз создавать новый объект, а затем он сохранит их все. Просто измените свой код на приведенный ниже

public function actionSave(){
  $request = \Yii::$app->request;
  foreach($request->post('Questions') as $key=>$value) {
    $model = new Answers();
    $model->load($request->post());
    $model->option_id = $value;
    $model->question_id = $key;
    $model->save();
  }
}

Также вы должны использовать блокировку транзакций при работе со связанными или несколькими записями, например, в этом случае вы должны либо сохранить их все, либо ничего в случае какой-либо ошибки или исключения, в настоящее время это не так. Если исключение или ошибка возникает на 4-м флажке, у вас все еще сохраняются первые 3 значения флажка. Попробуйте обернуть код, как показано ниже

public function actionSave(){
  $request = \Yii::$app->request;

  //start transaction
  $transaction=Yii::$app->db->beginTransaction();

  try{

    foreach ($request->post('Questions') as $key => $value) {
        $model = new Answers();
        $model->load($request->post());
        $model->option_id = $value;
        $model->question_id = $key;
        $model->save();
    }        

    //commit the transaction to save the records
    $transaction->commit();

  }catch(\Exception $e){
      //rollback the transaction so none of the checkboxes are saved 
      $transaction->rollBack();
      //do your stuff intimate the user by adding the message to a flash and redirecting 
  }
}
person Muhammad Omer Aslam    schedule 16.07.2019
comment
Спасибо большое! Это помогло мне! никогда не думал, что мне нужно создать модель внутри цикла - person Mirzhana Maxutova; 17.07.2019