0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

クイズ機能の実装(正誤を保存して最終結果を出す方法)

0
Last updated at Posted at 2026-08-13

コントローラーの作成

コマンドプロンプトで以下を実行する

コマンドプロンプト
rails g controller quiz

quiz_controllerに以下を記載する

app/controllers/quiz_controller.rb
class QuizController < ApplicationController
  before_action :set_current_question, only: [ :question, :answer, :answer_result ]

  def select_difficulty
  end

  def start
    difficulty = params[:difficulty]
    unless Question.difficulties.key?(difficulty)
      redirect_to quiz_path, alert: "難易度を選択してください。" and return
    end

    session[:quiz_question_ids] = Question.where(difficulty: difficulty).ids.shuffle
    session[:quiz_index] = 0
    session[:quiz_correct_count] = 0

    redirect_to quiz_question_path
  end

  def question
    redirect_to quiz_result_path unless @question
  end

  def answer
    redirect_to quiz_path and return unless @question

    user_answered_correct = params[:choice] == "true"
    correct = user_answered_correct == @question.answer
    session[:quiz_correct_count] += 1 if correct
    session[:quiz_last_correct] = correct

    redirect_to quiz_answer_result_path
  end

  def answer_result
    redirect_to quiz_path and return unless @question

    @correct = session[:quiz_last_correct]
    @last_question = last_question?
    render @correct ? :correct : :incorrect
  end

  def next_question
    session[:quiz_index] = session[:quiz_index].to_i + 1

    if current_question_id
      redirect_to quiz_question_path
    else
      redirect_to quiz_result_path
    end
  end

  def result
    @total = session[:quiz_question_ids]&.size.to_i
    @correct_count = session[:quiz_correct_count].to_i

    session.delete(:quiz_question_ids)
    session.delete(:quiz_index)
    session.delete(:quiz_correct_count)
  end

  private

  def current_question_id
    ids = session[:quiz_question_ids]
    ids && ids[session[:quiz_index].to_i]
  end

  def last_question?
    ids = session[:quiz_question_ids]
    ids && session[:quiz_index].to_i >= ids.size - 1
  end

  def set_current_question
    id = current_question_id
    @question = id && Question.find_by(id: id)
  end
end

Questionモデルを作る

コマンドプロンプトで以下を実行する

コマンドプロンプト
rails g model Question content:text difficulty:integer answer:boolean explanation:text

該当箇所を以下に変更

db/migrate/xxxxxxxxxxxxxx_create_questions.rb
class CreateQuestions < ActiveRecord::Migration[7.2]
  def change
    create_table :questions do |t|
      t.text :content, null: false # 変更はここから
      t.integer :difficulty, null: false, default: 0
      t.boolean :answer, null: false
      t.text :explanation, null: false # ここまでをコピーして貼り付けよう

      t.timestamps
    end
  end
end

変更したらコマンドプロンプトで以下を実行

コマンドプロンプト
rails db:migrate

モデルに以下を記載する

app/models/question.rb
class Question < ApplicationRecord
  enum :difficulty, { easy: 0, hard: 1 }

  validates :content, presence: true
  validates :explanation, presence: true
  validates :answer, inclusion: { in: [ true, false ] }
end

viewを作成する

app/views/quiz/に5つのviewファイルを作成して記載する

スクリーンショット 2026-08-13 235422.png

最終的に上の画像のように5つのhtmlファイルがあればOKなので以下を実行していこう!

1. select_difficulty.html.erbを作成して以下を記載(難易度を選択するページ)

app/views/quiz/select_difficulty.html.erb
<% content_for :title, "クイズ - 難易度選択" %>

<div class="quiz-container">
  <h1>〇✕クイズ</h1>
  <p>難易度を選んでください</p>

  <div class="quiz-choices">
    <%= button_to "かんたん", start_quiz_path(difficulty: "easy"), method: :post, class: "quiz-btn" %>
    <%= button_to "むずかしい", start_quiz_path(difficulty: "hard"), method: :post, class: "quiz-btn" %>
  </div>
</div>

2. app/views/quiz/question.html.erbを作成して以下を記載(クイズのページ)

app/views/quiz/question.html.erb
<% content_for :title, "クイズ - 問題" %>

<div class="quiz-container">
  <p class="quiz-progress">
    <%= session[:quiz_index].to_i + 1 %>問 / 全<%= session[:quiz_question_ids].size %>問
  </p>

  <h2 class="quiz-question"><%= @question.content %></h2>

  <div class="quiz-choices">
    <%= button_to "〇", quiz_answer_path(choice: "true"), method: :post, class: "quiz-btn maru" %>
    <%= button_to "✕", quiz_answer_path(choice: "false"), method: :post, class: "quiz-btn batsu" %>
  </div>
</div>

3. correct.html.erbを作成して以下を記載(正解のページ)

app/views/quiz/correct.html.erb
<% content_for :title, "正解" %>

<div class="quiz-container">
  <h2 class="quiz-result-title correct">正解</h2>
  <p class="quiz-question"><%= @question.content %></p>

  <%= link_to(@last_question ? "結果を見る" : "次の問題へ", quiz_next_question_path, class: "quiz-btn") %>
</div>

4. incorrect.html.erbを作成して以下を記載(不正解のページ)

app/views/quiz/incorrect.html.erb
<% content_for :title, "不正解" %>

<div class="quiz-container">
  <h2 class="quiz-result-title incorrect">不正解</h2>
  <p class="quiz-question"><%= @question.content %></p>
  <p class="quiz-explanation"><%= @question.explanation %></p>

  <%= link_to(@last_question ? "結果を見る" : "次の問題へ", quiz_next_question_path, class: "quiz-btn") %>
</div>

5. result.html.erbを作成して以下を記載(結果のページ)

app/views/quiz/result.html.erb
<% content_for :title, "クイズ結果" %>

<div class="quiz-container">
  <h1>結果発表</h1>
  <p class="quiz-score"><%= @total %>問中<%= @correct_count %>問正解</p>

  <%= link_to "もう一度挑戦する", quiz_path, class: "quiz-btn" %>
</div>

routes.rbに以下を記載する

config/routes.rb
get  "quiz",           to: "quiz#select_difficulty", as: :quiz
post "quiz",            to: "quiz#start",             as: :start_quiz
get  "quiz/question",   to: "quiz#question",          as: :quiz_question
post "quiz/answer",     to: "quiz#answer",             as: :quiz_answer
get  "quiz/answer",     to: "quiz#answer_result",      as: :quiz_answer_result
get  "quiz/next",       to: "quiz#next_question",      as: :quiz_next_question
get  "quiz/result",     to: "quiz#result",             as: :quiz_result

問題を作成する

ここから問題を作成していきます!少し難しいのでよく見ながら頑張っていきましょう!

db/seeds.rbに以下を記載する

db/seeds.rb
Question.delete_all

easy_questions = [
  { content: "地球は太陽の周りを回っている。", answer: true,
    explanation: "地球は太陽を中心とした公転軌道を約365日かけて一周しています。" },
  { content: "1年は10ヶ月である。", answer: false,
    explanation: "1年は12ヶ月です。" },
  { content: "富士山は日本一高い山である。", answer: true,
    explanation: "富士山の標高は3776mで、日本国内で最も高い山です。" },
  { content: "魚は肺で呼吸する。", answer: false,
    explanation: "多くの魚はえら呼吸で水中の酸素を取り込みます。" },
  { content: "1週間は7日である。", answer: true,
    explanation: "1週間は日〜土までの7日間です。" }
]

hard_questions = [
  { content: "光の速さは音の速さより速い。", answer: true,
    explanation: "光速は秒速約30万km、音速は秒速約340mで、光の方が圧倒的に速いです。" },
  { content: "人間の骨は年齢を重ねるほど数が増える。", answer: false,
    explanation: "新生児は約300個の骨を持ちますが、成長とともに骨が結合し、成人では約206個になります。" },
  { content: "水は0度で凍り、100度で沸騰する(1気圧の場合)。", answer: true,
    explanation: "標準大気圧下での水の融点は0度、沸点は100度です。" },
  { content: "DNAの二重らせん構造を発見したのはアインシュタインである。", answer: false,
    explanation: "DNAの二重らせん構造を発見したのはワトソンとクリックです。" },
  { content: "地球の大気の主成分は酸素である。", answer: false,
    explanation: "地球の大気の約78%は窒素で、酸素は約21%です。" }
]

easy_questions.each { |attrs| Question.create!(attrs.merge(difficulty: :easy)) }
hard_questions.each { |attrs| Question.create!(attrs.merge(difficulty: :hard)) }

puts "Seeded #{Question.count} questions."

これは例なのでここから自分用の質問に変更していきましょう!

1. 問題の変更

まず、上に書いているeasy_questionsの方が簡単な問題で下に書いてあるhard_questionsが難しい問題になります。ここから変更していきますが、

{ content: "地球は太陽の周りを回っている。", answer: true,
    explanation: "地球は太陽を中心とした公転軌道を約365日かけて一周しています。" },

このような形のものがたくさんあると思いますが、問題を変更する部分はcontentの後の" "の中です

例の場合ここを変更する
地球は太陽の周りを回っている。

2. 正誤の判定

正解か不正解かの判定はanswer:のところを変更します
正解を〇と✕のどちらにしたいかによって変わるので注意して変更していきましょう

正解を〇にしたい場合

seeds.rb
answer: true

正解を✕にしたい場合

seeds.rb
answer: false

3. 解説を変更する

解説はexplantationの後の" "の中を変更します

例の場合ここを変更する
地球は太陽を中心とした公転軌道を約365日かけて一周しています。

1~3を変更して自分のクイズにしよう!

サイトに反映させる

seeds.rbを変更しただけではrails sをしたときにサイトに反映されないので以下をコマンドプロンプトで実行しましょう

コマンドプロンプト
rails db:seed

※上のコードを実行した後にseeds.rbの中身を変更した場合、再度rails db:seedを実行してください!

サイトに変更後が反映されないため

問題数を変更する場合

今の問題はどちらのクイズも5問になっているので、増やしたい場合はseeds.rbの{ }の部分を下に追加して、減らしたい場合はいらない{ }の部分を消すだけで大丈夫です

※問題を増やす場合、最後の質問の} の後には何もついていないが、それ以外の質問には}の後に,を付けるので気を付けてください!

また、変更後には

コマンドプロンプト
rails db:seed

コマンドプロンプトで実行するのを忘れないよにしよう

最後に

実装おつかれ様でした!あとは自分の中身にしていくだけなので頑張っていきましょう!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?