ruby on rails を AWS Cloud9で実施 4  QandAサイト作成　バリデーション追加まで

https://qiita.com/TaichiEndoh/items/35294ff656499d9bbf8d

https://qiita.com/TaichiEndoh/items/9c19319df04a279403a3

https://qiita.com/TaichiEndoh/items/057d35eff8cadbd434ba

具体的な説明は上記を確認願います


環境　AWS Cloud9
environment type EC2
instance type t2.micro
platform ubuntu server 18.04 LTS

# QandAサイト作成

## 新規プロジェクト作成

今回もバージョンを指定して立ち上げたいので

```
 rails new qanda _7.0.0_
```
qanda　プロジェクトが確認できます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/50ae80c6-6006-a0ff-fb68-59c83dca5888.png)

development.rb　の確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/58ce0e32-d6a3-e4c6-5d84-8f751dd23daa.png)

ホワイトリストを一時的にクリア　＊学習用の方法です

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/c875b3c1-6170-2c2a-de5d-a19420cd0aeb.png)


再度
railsサーバー立ち上げるコマンド
```
rails s
```

## 質問コントローラー作成
AWS Cloud9 ターミナルで実行
```
rails g controller questions
```
以下を変更
```questions_controller.rb
class QuestionsController < ApplicationController
  # 質問一覧表示
  def index
  end
  
  # 質問詳細ページ表示
  def show
  end
  
  # 質問の作成
  def new
  end
  
  # 質問の登録
  def create
  end
  
  # 質問の編集
  def edit
  end
  
  # 質問の更新
  def update
  end
  
  # 質問の削除
  def destroy
  end
end
```

## 質問モデル作成

AWS Cloud9 ターミナルで実行
```
rails g model Question name:string title:string content:text
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/fa81e80c-548b-08ab-5dc0-0fb41176305c.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/2e5a0105-eb4b-5a27-d829-1f4a821e5c93.png)

上記のマイグレーションファイルのスペルミスがないことを確認し
マイグレーションを実施します

Railsは、マイグレーションファイルという設定ファイルを自動作成して
それをmigrationコマンドで、データベースに反映させます

以下のコマンドでデータベース設定を反映することが可能です
```
rails db:migrate
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/da668267-54a0-618b-5a0b-356dfe9ad1fd.png)


## データベース構造の確認
データベースをコマンドで操作できるモードに変更します
以下のコマンドを利用します
```
rails dbconsole

#内部で確認
.schema questions
#終了するとき
.q
```

## ルーテングを設定する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/f5b2281c-5602-943a-eece-3f24508e890b.png)

ルーティングはユーザーからのリクエストを
コントローラーのアクションに割り振る
役割を担うものです
resources :questions
とすることで CRUD アプリケーションで使用する
ルーテングを自動生成することができます！

```routes.rb
Rails.application.routes.draw do
  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

  # Defines the root path route ("/")
  # root "articles#index"
  resources :questions
end
```

AWS Cloud9 ターミナルで実行
```
rails routes
```

## views　作成

```app/views/questions/new.html.erb
<h1>New question</h1>
<%= form_with model: @question do |form| %>
  <div>
    <%= form.label :title %><br>
    <%= form.text_field :title %>
  </div>
  <div>
    <%= form.label :name %><br>
    <%= form.text_field :name %>
  </div>
  <div>
    <%= form.label :content %><br>
    <%= form.text_area :content %>
  </div>
  <div>
    <%= form.submit %>
  </div>
<% end %>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/40dd238a-6297-ccae-259b-a2ae9596d046.png)


```questions_controller.rb
class QuestionsController < ApplicationController
  # 質問一覧表示
  def index
  end
  
  # 質問詳細ページ表示
  def show
    # p params[:id]
    @question = Question.find(params[:id])
    # p @question
  end
  
  # 質問の作成
  def new
    @question = Question.new
  end
  
  # 質問の登録
  def create
    # Questionモデルを初期化
    @question = Question.new(question_params)
    # QuestionモデルをDBへ保存
    @question.save
    # showへリダイレクト
    redirect_to @question
  end
  
  # 質問の編集
  def edit
  end
  
  # 質問の更新
  def update
  end
  
  # 質問の削除
  def destroy
  end
  
  private
  def question_params
    params.require(:question).permit(:title, :name, :content)
  end
end
```
以下の部分はストロングパラメーターを利用しています
ストロングパラメーターを利用することで
指定したデータ以外を送ってくる
悪意のあるリクエストを受けた際に
permit　許可　しないことになり
データベースの変更がされなくなるので
データの取り扱いがより　安全になります
```
  private
  def question_params
    params.require(:question).permit(:title, :name, :content)
  end
```
https://qiita.com/ozackiee/items/f100fd51f4839b3fdca8

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/526cda46-5dd1-8279-cd1b-06f7a934e2ef.png)

```app/views/questions/show.html.erb
<h1>Show</h1>
<p>
  Title:<br>
  <%= @question.title %>
</p>

<p>
  Name:<br>
  <%= @question.name %>
</p>

<p>
  Content:<br>
  <%= @question.content %>
</p>
```

## 一覧表示を実行する　ページの作成

controllerの変更


```app/controllers/questions_controller.rb
class QuestionsController < ApplicationController
  # 質問一覧表示
  def index
    @questions = Question.all
    # p @questions
  end
  
  # 質問詳細ページ表示
  def show
    # p params[:id]
    @question = Question.find(params[:id])
    # p @question
  end
  
  # 質問の作成
  def new
    @question = Question.new
  end
  
  # 質問の登録
  def create
    # Questionモデルを初期化
    @question = Question.new(question_params)
    # QuestionモデルをDBへ保存
    @question.save
    # showへリダイレクト
    redirect_to @question
  end
  
  # 質問の編集
  def edit
  end
  
  # 質問の更新
  def update
  end
  
  # 質問の削除
  def destroy
  end
  
  private
  def question_params
    params.require(:question).permit(:title, :name, :content)
  end
end
```

viewsの作成

```app/views/questions/index.html.erb
<h1>Questions</h1>
<table>
  <tr>
    <th>ID</th>
    <th>Title</th>
    <th>Name</th>
    <th>Content</th>
    <th></th>
  </tr>
  <% @questions.each do |question| %>
  <tr>
    <td><%= question.id %></td>
    <td><%= question.title %></td>
    <td><%= question.name %></td>
    <td><%= question.content %></td>
    <td><%= link_to 'show', question_path(question) %></td>
  </tr>
  <% end %>
</table>
```

## バリデーションを追加する

現在のデータベースですと
未入力でも保存できてしまうので
バリデーションを実施します

詳しいまとめは以下となります

https://qiita.com/h1kita/items/772b81a1cc066e67930e


models ファイルの変更を行います
```app/models/question.rb
class Question < ApplicationRecord
  validates :title, presence: true
  validates :name, presence: true
  validates :content, presence: true, length: { minimum: 5 }
end
```

presence: true で未入力チェックができます

length: { minimum: 5 }　
lengthは文字数の指定を変更できます　　
上のコマンドでは5文字以上の入力が必要になります！

controllerの変更
 def createの部分 質問の登録　の関数を変更します

```app/controllers/questions_controller.rb
class QuestionsController < ApplicationController
  # 質問一覧表示
  def index
    @questions = Question.all
    # p @questions
  end
  
  # 質問詳細ページ表示
  def show
    # p params[:id]
    @question = Question.find(params[:id])
    # p @question
  end
  
  # 質問の作成
  def new
    @question = Question.new
  end
  
  # 質問の登録
  def create
    # Questionモデルを初期化
    @question = Question.new(question_params)
    # QuestionモデルをDBへ保存
    if @question.save
      # showへリダイレクト
      redirect_to @question
    else
      render 'new', status: :unprocessable_entity
    end
  end
  
  # 質問の編集
  def edit
  end
  
  # 質問の更新
  def update
  end
  
  # 質問の削除
  def destroy
  end
  
  private
  def question_params
    params.require(:question).permit(:title, :name, :content)
  end
end
```

viewも変更

```app/views/questions/new.html.erb
<h1>New question</h1>
<%= form_with model: @question do |form| %>
  <% if @question.errors.any? %>
    <div>
      <ul>
        <% @question.errors.full_messages.each do |message| %>
          <li><%= message %></li>
        <% end %>
      </ul>
    </div>
  <% end %>
  <div>
    <%= form.label :title %><br>
    <%= form.text_field :title %>
  </div>
  <div>
    <%= form.label :name %><br>
    <%= form.text_field :name %>
  </div>
  <div>
    <%= form.label :content %><br>
    <%= form.text_area :content %>
  </div>
  <div>
    <%= form.submit %>
  </div>
<% end %>
```
これで　投稿内容が空欄だったり
5文字以下の内容投稿の場合に
投稿できないように　
バリデーションすることができました

皆様に使用していただくデータベースを作成していると
誰かが間違ってボタンを押してしまい　そのままにしていたため
なぜそのレコードがあるか　わからない問題に直面することがあります

バリデーションでは　そのような問題を回避できるので非常に重要です！


# 次回は　質問の編集、削除、そして同じソースコードをまとめる作業を行います

一つのテーブルを利用した機能は次回で完成できます！！！

投稿した内容を
編集や削除しなければ
機能面としても使いにくいため調整します

さらにソースコードをまとめる
リファクタリングを行うことで
とても汎用性のあるソースコードが書けます

興味のある方は以下をクリック願います！！

https://qiita.com/TaichiEndoh/items/809d7e94195265c0a201