診断機能を作りたいあなたに

こんにちは
RUNTEQにて卒業制作で診断アプリを作ってます
今回はとってもシンプルなYESNO形式で診断する機能を共有いたします
診断結果の出力は別途共有いたします
初めての公開記事で頼りないところもございますが、よろしくお願いいたします

# **ルーティングを定義**

ルート側にdiagnoses(診断機能)を追加します

現在のroutes.rbでは、診断機能を提供するresources :diagnosesに対してindexとshowアクションしかルートが設定されていませんが、トップページから診断フォーム（newアクション）に進む必要があります

---

```ruby
# 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への正しいルートを指すようにします(診断機能にて修正)
```erb
<div class="start-button-container">
      <%= link_to '診断スタート', new_diagnosis_path, class: 'start-button' %>
</div>
```

# **コントローラーを定義**

### **コントローラーの生成**

以下のコマンドを使用して diagnoses コントローラーを生成します

```ruby
$ docker compose exec web rails g controller diagnoses
```

### **コントローラーの編集**

生成された app/controllers/diagnoses_controller.rb ファイルを開きます
フラッシュメッセージは時間があればj18n化して整えるのもいいかもしれませんが、ここでは省きます

```ruby
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方式です

```erb
<%= 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 に診断ページ用のスタイルを読み込みます
```scss
/*app/assets/stylesheets/application.scssにdiagnoses.scssをインポート*/
@import 'diagnoses';
```

### **HTMLの整理**

診断ページ `app/views/diagnosis/new.html.erb` のHTMLも、クラスを適切に指定してデザインを調整します

```erb
<%= 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