迷い人

日々勉強。勉強の先に何か見つかるといいなぁ

【laravel】理解度テスト表示機能を追加

本日は理解度テスト表示機能を追加していきます。

 

 

やったこと

  • check_testsテーブル、checktest_problemsテーブル、checktest_answersテーブルの追加
  • CheckTestControllerの追加、viewchecktestアクションの追加
  • 追加したテーブルのモデルをそれぞれ追加
  • ルーティングの設定

 

追加したテーブル 

check_testsテーブル
  • id                      integer PK AI
  • curriculum_id   integer
  • name                text

1つのカリキュラムで複数の確認テストが持てる

 

check_test_problemsテーブル
  • id                       integer PK AI
  • content              text
  • checktest_id      integer

1つの確認テストで複数の問題が持てる

 

check_test_answersテーブル
  • id                                       integer PK AI
  • checktest_problem_id      integer
  • answer                              text
  • correct_flg                         integer

1つの問題で複数の回答が持てる

 

イメージはこんなん。

 

確認テストA

問題1

  • 回答1
  • 回答2
  • 回答3

問題2

  • 回答4
  • 回答5

問題3

  • 回答6
  • 回答7
  • 回答8
  • 回答9

 

viewchecktestアクションのポイント

app/Http/Controllers/CheckTestController.php

public function viewchecktest($id='1') {
//理解度テスト番号に対応する問題を全て取得(例えば10問) $problems = CheckTestProblem::where(['checktest_id' => $id])->get(['id','content']);
//各問題に対応する選択肢を全て取得(例えば選択肢は4つ) foreach($problems as $problem){ $i = 0; $answers = CheckTestAnswer::where(['checktest_problem_id' => $problem->id])->get(['id','answer']); foreach($answers as $answer){ $data[$problem->content][$i] = [$problem->id,$answer->id,$answer->answer]; $i++; } } //生成されるdataのイメージ //$data = [ // '問題1' => [[1,1,'回答1_1'],[1,2,'回答1_2'],[1,3,'回答1_3'],[1,4,'回答1_4']], // '問題2' => [[2,5,'回答2_1'],[2,6,'回答2_2'],[2,7,'回答2_3'],[2,8,'回答2_4']] //];
//チェックテストのビューが格納されいているパス $viewfilename = "checktest.checktest"; return view($viewfilename, ['data' => $data, 'checktest_id' => $id]); }

 

連想配列の多次元配列を使いました。

 

問題本文(例:問題1)をキーにして、そのバリューが多次元配列になっています。バリューに対応する配列は選択肢の数だけあり、1つの選択肢は3つのバリューを持ちます。

 

  • 問題番号(例:1)
  • 回答番号(例:1〜4)
  • 回答内容(例:回答1_1)

 

checktest.blade.phpのポイント

resouces/views/checktest/checktest.blade.php

@extends('layouts.checktestapp') @section('title', 'checktest_name') @section('content') <p>確認テスト(新)</p> <form method="POST" action="/checktest/result"> {{ csrf_field() }} @foreach($data as $key=>$val) <p><?php echo $key; ?></p> @foreach($val as $key2=>$val2) <input type="radio" name="item[{{$val2[0]}}]" value ="{{$val2[1]}}"><?php echo $val2[2]; ?> <br> @endforeach <br> @endforeach <input type="hidden" name="checktest_id" value="{{$checktest_id}}"> <input type="submit"> </form> @endsection

 

ラジオボタンで選択式にしています。

 

ラジオボタンのグループはnameで指定していてforeach重ねて、val2[0]とすることで問題番号を格納しています。また、val2[1]の回答番号がvalue、val2[2]の回答内容はそのまま表示させます。

 

checktest_idはこの次の処理で理解度テストの採点をするために使うので、hidden設定で組み込んで、postで送信できるようにしています。

 

 

ルートのポイント

Route::get('/checktest/{id?}', 'CheckTestController@viewchecktest');

これといってポイントは無し。 

 

あとがき 

Eloquentの使い方について、理解するのに時間がかかった。後から別記事でまとめておきたい。

 

また、連想配列と多次元配列についてもイメージしにくかった。Railsの時の配列とハッシュの使い方でも同じように詰まったことを思い出しました。こちらも別記事でまとめておきたい。

 

課題感

もっとスマートなDB管理とコーディングができないか。コントローラに詰め込みすぎている感じ。