Railsアプリで単一回答のアンケートアプリを作ります。
今回はユーザーが回答する箇所を実装してみます。
環境
Ruby 3.3.0
Rails 7.1.3.2
モデルを生成します。
rails new sample_radio_qa
cd sample_radio_qa
bin/rails g scaffold User name
bin/rails g scaffold Question content
bin/rails g scaffold Radio content question:belongs_to
bin/rails g scaffold Answer user:belongs_to question:belongs_to radio:belongs_to
bin/rails db:migrate
質問は複数の項目を持ちます。
# app/models/question.rb
class Question < ApplicationRecord
has_many :radios
end
初期データを生成します。
今回はログインユーザーの管理、管理者による質問の編集機能は省きます。
# db/seeds.rb
User.find_or_create_by(name: "ユーザー1")
User.find_or_create_by(name: "ユーザー2")
q1 = Question.find_or_create_by(content: "好きな映画のジャンルは?")
["アクション", "コメディー", "ドラマ", "ホラー"].each do |content|
Radio.find_or_create_by!(content: content, question: q1)
end
q2 = Question.find_or_create_by(content: "好きな果物は?")
["いちご", "もも", "みかん", "りんご", "ぶどう"].each do |content|
Radio.find_or_create_by!(content: content, question: q2)
end
bin/rails db:seed
最初の質問を開きます。
bin/rails server
open http://localhost:3000/questions/1
質問の下に回答項目をラジオボタンで表示します。
# app/controllers/questions_controller.rb
def show
current_user = User.second # TODO: ログインユーザーを取得する。
@answer = Answer.find_or_initialize_by(user: current_user, question: @question)
end
# app/views/questions/show.html.erb
...
<%= render "answers/form", answer: @answer, question: @question %>
# app/views/answers/_form.html.erb
...
<div>
<%= form.collection_radio_buttons :radio_id, @question.radios, :id, :content %>
</div>
今回は質問の編集権限を考えていないので質問の編集リンクと削除ボタンを残しています。
製品では回答のテキストフィールドは不要になります。
回答処理を実装します。
保存後のパスを回答から質問に変更します。
# app/controllers/answers_controller.rb
def create
@answer = Answer.new(answer_params)
@question = @answer.question
if @answer.save
redirect_to @question, notice: "Answer was successfully created."
else
render "questions/show", status: :unprocessable_entity
end
end
def update
@question = @answer.question
if @answer.update(answer_params)
redirect_to @question, notice: "Answer was successfully updated."
else
render "questions/show", status: :unprocessable_entity
end
end
レイアウトや文言など見栄えを洗練する必要がありますが、機能としては完成しました。
以下、項目を選択しなかった場合のエラー表示です。
おまけ
テンプレートが受け取るローカル変数をマジックコメントで定義する。
回答項目で改行する。
# app/views/answers/_form.html.erb
<%# locals: (answer:, question:) -%>
...
<%= form.collection_radio_buttons(:radio_id, question.radios, :id, :content) do |b| %>
<%= b.label(style: "display: block") { b.radio_button + b.text } %>
<% end %>
▼この記事がいいね!と思ったらブックマークお願いします