2020-12-31に投稿

2020.12.31 * テスト機能作成

本日のゴール

■ テスト機能を作る
image.png
設計を少し見直しました。
単語の編集機能は無くして、追加・削除のみにします。

Test画面生成

チャプターごとに単語テストができる画面を作ります!
久々にこのコマンド
$ rails g controller Tests
tests_controller.rbにテスト画面表示用のindexアクションを作成します。

class TestsController < ApplicationController
    def index
        @chapter_id = params[:chapter_id]
        @words = Word.where(chapter_id: @chapter_id)
    end

routes.rbには以下を追加

get 'test/', to: 'tests#index'

chapters/index.html.erbにテスト画面へのリンクを追加

<% @chapters.each do |chapter| %>
    <div>
        <%= chapter.name %>
        <%= link_to 'Show Words', words_path(chapter_id: chapter.id) %>
        <%= link_to 'TEST', test_path(chapter_id: chapter.id) %>
    </div>
<% end %>

こんな感じです
image.png

テスト画面のviewを作成します。
tests/index.html.erb

<h1>TEST - CHAPTER<%= @chapter_id %></h1>
<div>
<%= form_with url: score_path do |f| %>
    <% @words.each do |word| %>
        <div>
            <%= word.english %>
            <%= f.text_field :"answers[#{word.id}]" %>
        </div>
    <% end %>
    <%= f.hidden_field :chapter_id, :value => @chapter_id %>
    <%= f.submit 'SUBMIT' %>
<% end %>
</div>

単語のIDと回答をanswersというハッシュに格納してコントローラに渡すようにしています。
(キーがID, 回答が値)
hidden_fieldのチャプターIDはスコア画面で表示させるためのものです。

画面はこうなりました。
image.png

テストを採点する

tests_controller.rb

    def score
        answers = params[:answers]
        should_retest_values = {}
        session[:answers] = answers
        # 正誤判定
        answers.each do |answer|
            should_retest = is_wrong(answer)
            should_retest_values[answer[0]] = should_retest
        end
        # wordsテーブルのshould_retestを更新
        should_retest_values.each do |k, v|
            word = Word.find(k)
            word.should_retest = v
            word.save
        end
        # 正答数を算出
        score = count_correct_answers
        # テンプレートに返却
        redirect_to showscore_path(score: score, chapter_id: params[:chapter_id])
    end

    def show
        @score = params[:score]
        @chapter_id = params[:chapter_id]
        @words = Word.where(chapter_id: @chapter_id)
        @answers = session[:answers]
    end

    private

    def is_wrong(answer)
        correct_answer = Word.find(answer[0])
        return answer[1] != correct_answer.japanese
    end

    def count_correct_answers
        Word.where(should_retest: false).size
    end

scoreメソッドがやっている処理は以下のとおりです。
1. viewから渡された回答をセッションに入れる(スコア画面で表示させるため)
2. 正誤判定し、{ ID: 再テストtrue/false } という形式のハッシュを作成
3. ハッシュの値をもとにDB(wordsテーブルのshould_retestカラム)を更新
4. スコア(正答数)を算出
5. スコア画面にリダイレクト

showメソッドはスコア画面を表示します。
ルーティングは以下のようにしました。
routes.rb

  post 'score/', to:'tests#score'
  get 'showscore/', to:'tests#show'

スコア画面作成

tests/show.html.erb

<h1>SCORE - CHAPTER<%= @chapter_id %></h1>
<div>
    score:<%= @score %>
</div>
<div>
    <% @words.each do |word| %>
    <p>
        <%= word.english %>
        <%= word.japanese %>
        <%= @answers[word.id.to_s] %>
    </p>
    <% end %>
</div>

showメソッドから渡された変数を使ってスコア、英単語・正解・ユーザの回答を表示させています。
image.png

DBの値もちゃんと更新されました!
image.png

おわり*0 v 0

ツイッターでシェア
みんなに共有、忘れないようにメモ

view_list Ruby on Railsを使ったwebアプリ開発の記録
第5回 2020.11.12 * 単語の一覧表示
第6回 2020.11.16 * 編集機能
第7回 2020.11.17 * 画面設計
第8回 2020.12.11 * chapter機能
第9回 2020.12.31 * テスト機能作成

same.__.same

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント