ruby on rails を AWS Cloud9で実施 6  QandAサイト作成　新たなテーブル作成


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

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

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

https://qiita.com/TaichiEndoh/items/522e956d569e5bbd7b8d

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

# 前回の続きでQandAサイト作成　今回は新たなテーブルを作成するところから始めます
### 今回は前回の投稿テーブルに紐づくテーブルを作成します！

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

## モデル作成

Rails が提供するModelは、
原則としてデータベース上にある
テーブルと対応しており

テーブルのデータを簡単に操作する機能を提供します

#### rails g model コマンド
rails g model コマンドで user に関するモデルを作成します
rails g modelの使い方
```
$ rails g model モデル名
```

#### AWS Cloud9 ターミナルで実行
```
rails g model Answer name:string content:text question:references
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/1b5acdc0-d56b-9886-72fe-904e1e9a2e1f.png)

上記コマンドで　User　はモデル名

その下がデータベースのデータの構造です

name:string カラム名:データ型 投稿者の名前を保存する
content:text カラム名:データ型 内容を保存する

question:references questionテーブルとリレーション
↑どの投稿に対する回答かを管理するための設定

スペース区切りで複数　設定できます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/fca9933f-1f2e-1a6d-dd33-11bf1333180f.png)

```
class CreateAnswers < ActiveRecord::Migration[7.0]
  def change
    create_table :answers do |t|
      t.string :name
      t.text :content
      t.references :question, null: false, foreign_key: true

      t.timestamps
    end
  end
end
```

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

以下の記述は　カラムがnullになることを禁止
```
null: false
```

外部キー制約の設定を有効にします
```
foreign_key: true
```
レコードの作成日時と更新日時を管理するカラムを作る
```
t.timestamps
```

#### マイグレーション
マイグレーションは Rails で自動生成した設定内容をデータベースに反映させます

マイグレーションをもう少し、簡単に言うと
データベースのテーブルを作成・変更するための仕組みです

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

以下のコマンドでデータベース設定を反映することが可能です
```
rails db:migrate
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/68393a54-818c-fe64-2546-8293295b9f70.png)

#### 他のモデルとの関連を記述

１ 対 多 の内容を表示できるように　has_many　を使用
has_many :answers


```app/models/question.rb
class Question < ApplicationRecord
  has_many :answers, dependent: :destroy
  
  validates :title, presence: true
  validates :name, presence: true
  validates :content, presence: true, length: { minimum: 5 }
end
```

#### 紐づくルーティングの生成と確認

```config/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"
  root "questions#index"
  resources :questions do
    resources :answers
  end
end

```
resources :questions 
↓
resources :questions do
    resources :answers

とすることで　questions　に紐づく
answers　に関するルーティングが自動生成されます


#### ルーティングの確認

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

これで投稿画面に紐づくテーブル作成とルーティングまでができました！

## コントローラとViewの作成

#### コントローラーを作成
AWS Cloud9 ターミナルで実行
```
rails g controller Answers
```

作成されたapp/controllers/answers_controller.rb 
の内容を変更

```app/controllers/answers_controller.rb 

class AnswersController < ApplicationController
  # 回答の登録
  def create
    # p params
    @question = Question.find(params[:question_id])
    @question.answers.create(answer_params)
    redirect_to question_path(@question)
  end
  
  # 回答の削除
  def destroy
    @question = Question.find(params[:question_id])
    @answer = @question.answers.find(params[:id])
    @answer.destroy
    redirect_to @question, status: :see_other
  end
  
  private
  def answer_params
    params.require(:answer).permit(:name, :content)
  end
end
```

#### Viewの変更

app/views/questions/show.html.erb
を変更します

```app/views/questions/show.html.erb
<h1>確認画面</h1>
<p>
  元の投稿タイトル:<br>
  <%= @question.title %>
</p>

<p>
  投稿者名:<br>
  <%= @question.name %>
</p>

<p>
  投稿内容:<br>
  <%= @question.content %>
</p>

<h2>投稿に対する補足</h2>
<% @question.answers.each do |answer| %>
  <p>
    投稿者名:<br>
    <%= answer.name %>
  </p>
  <p>
    投稿内容:<br>
    <%= answer.content %>
  </p>
  <p>
    <%= link_to '削除する', [answer.question, answer],
      data: { turbo_method: 'delete', turbo_confirm: '本当に削除しますか?' } %>
  </p>
<% end %>

<h2>追加投稿 or 意見</h2>
<%= form_with model: [@question, @question.answers.build] do |form| %>
  <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 %>
<%= link_to 'top', questions_path %>
```