■ テスト機能を作る
設計を少し見直しました。
単語の編集機能は無くして、追加・削除のみにします。
チャプターごとに単語テストができる画面を作ります!
久々にこのコマンド
$ 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 %>
テスト画面の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はスコア画面で表示させるためのものです。
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メソッドから渡された変数を使ってスコア、英単語・正解・ユーザの回答を表示させています。
おわり*0 v 0
第5回 | 2020.11.12 * 単語の一覧表示 |
第6回 | 2020.11.16 * 編集機能 |
第7回 | 2020.11.17 * 画面設計 |
第8回 | 2020.12.11 * chapter機能 |
第9回 | 2020.12.31 * テスト機能作成 |
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント