【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管理とコーディングができないか。コントローラに詰め込みすぎている感じ。