こんにちは
RUNTEQにて卒業制作で診断アプリを作ってます
今回はとってもシンプルなYESNO形式で診断する機能を共有いたします
診断結果の出力は別途共有いたします
初めての公開記事で頼りないところもございますが、よろしくお願いいたします
ルーティングを定義
ルート側にdiagnoses(診断機能)を追加します
現在のroutes.rbでは、診断機能を提供するresources :diagnosesに対してindexとshowアクションしかルートが設定されていないが、トップページから診断フォーム(newアクション)に進む必要があります
# routes.rb
Rails.application.routes.draw do
# (省略)
root "static_pages#top"
# 診断機能にて追加
resources :diagnoses, only: %i[index show new create]
end
diagnoses#new
へのルートに変更
Railsのルーティングヘルパーで、diagnoses#newへの正しいルートを指すようにします(診断機能にて修正)
<div class="start-button-container">
<%= link_to '診断スタート', new_diagnosis_path, class: 'start-button' %>
</div>
コントローラーを定義
コントローラーの生成
以下のコマンドを使用して diagnoses コントローラーを生成します
$ docker compose exec web rails g controller diagnoses
コントローラーの編集
生成された app/controllers/diagnoses_controller.rb ファイルを開きます
フラッシュメッセージは時間があればj18n化して整えるのもいいかもしれませんが、ここでは省きます
class DiagnosesController < ApplicationController
def new
@diagnosis = Diagnosis.new
end
def show
@diagnosis = Diagnosis.find(params[:id])
end
def create
@diagnosis = Diagnosis.new(diagnosis_params)
# すべての質問が回答されているかチェック
# 回答が欠けている場合、「"選択されていない回答があります"」と表示
if diagnosis_params[:question1].blank? || diagnosis_params[:question2].blank? || diagnosis_params[:question3].blank?
flash[:alert] = "選択されていない回答があります"
render :new
else
# 各質問の回答を連結して一つの文字列にする
@diagnosis.question = "#{diagnosis_params[:question1]}#{diagnosis_params[:question2]}#{diagnosis_params[:question3]}"
# すべての質問が回答されている場合
if @diagnosis.save
flash[:notice] = "診断が完了しました"
redirect_to diagnosis_path(@diagnosis)
end
end
end
private
# ストロングパラメータの中にすべての質問が回答されているかチェック
# Web上で受けたパラメータが、安全であるかどうか確認をおこなった上で、
# 取得することができる仕組みでここでスペルミスとデータが欠如すると、
# param is missing or the value is emptyのエラーが発生する
def diagnosis_params
params.require(:diagnosis).permit(:question1, :question2, :question3)
end
end
diagnoses**/new.html.erb ファイル生成・編集**
診断の設問を表示するページを生成し、編集します
今回は、設問3つのYESNO方式です
<%= form_for(@diagnosis, url: diagnoses_path, method: :post, class: 'form-horizontal') do |f| %>
<div class="form-group">
<label><!--ここは各自好きな質問で--></label>
<%= f.radio_button :question1, "1" %> YES
<%= f.radio_button :question1, "2" %> NO
</div>
<div class="form-group">
<label><!--ここは各自好きな質問で--></label>
<%= f.radio_button :question2, "1" %> YES
<%= f.radio_button :question2, "2" %> NO
</div>
<div class="form-group">
<label><!--ここは各自好きな質問で--></label>
<%= f.radio_button :question3, "1" %> YES
<%= f.radio_button :question3, "2" %> NO
</div>
<!--診断結果の実装にてリンクを付ける-->
<%= link_to "診断結果を見る", '/food', class: 'result'%>
<% end %>
CSS で見た目を整える
application.scss
に診断ページ用のスタイルを読み込む
こちらは、各自好きなように修正しますので、内容は省きます
app/assets/stylesheets/application.scss
にdiagnoses.scss
をインポート
application.scss に診断ページ用のスタイルを読み込みます
/*app/assets/stylesheets/application.scssにdiagnoses.scssをインポート*/
@import 'diagnoses';
HTMLの整理
診断ページ app/views/diagnosis/new.html.erb
のHTMLも、クラスを適切に指定してデザインを調整します
<%= form_for(@diagnosis, class: 'form-horizontal') do |f| %>
<div class="diagnosis-wrapper">
<div class="row">
<div class="diagnosis-inner-text">
<p><!--ここは各自好きな質問で--></p>
</div>
<div class="col-6">
<%= f.radio_button :question1, "1", id: "question1_yes", class: "hidden-radio" %>
<label for="question1_yes" class="button yes-button">YES</label>
</div>
<div class="col-6">
<%= f.radio_button :question1, "2", id: "question1_no", class: "hidden-radio" %>
<label for="question1_no" class="button no-button">NO</label>
</div>
<div class="diagnosis-inner-text">
<p><!--ここは各自好きな質問で--></p>
</div>
<div class="col-6">
<%= f.radio_button :question2, "1", id: "question2_yes", class: "hidden-radio" %>
<label for="question2_yes" class="button yes-button">YES</label>
</div>
<div class="col-6">
<%= f.radio_button :question2, "2", id: "question2_no", class: "hidden-radio" %>
<label for="question2_no" class="button no-button">NO</label>
</div>
<div class="diagnosis-inner-text">
<p><!--ここは各自好きな質問で--></p>
</div>
<div class="col-6">
<%= f.radio_button :question3, "1", id: "question3_yes", class: "hidden-radio" %>
<label for="question3_yes" class="button yes-button">YES</label>
</div>
<div class="col-6">
<%= f.radio_button :question3, "2", id: "question3_no", class: "hidden-radio" %>
<label for="question3_no" class="button no-button">NO</label>
</div>
</div>
<div class="diagnosis-inner-text">
<!--診断結果の実装にてリンクを付ける-->
<%= f.submit "診断結果を見る", class: 'result' %>
</div>
</div>
<% end %>
診断結果を出力する方法については下記にて作成しましたので、
ご確認ください
https://qiita.com/jiantaiyiteng1/items/4c7fe574ab150e70c77c