【Ruby on Rails】コメント機能実装

# 目標
![コメント.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/8849d33c-25c8-caf9-c190-22ec6b6456a4.gif)

# 開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina

# 前提
※　▶◯◯　を選択すると、説明等が出てきますので、
　　よくわからない場合の参考にしていただければと思います。

- [deviseでログイン環境構築](https://qiita.com/japwork/items/275110b810965fbdf72f)
- [ログインユーザーのみができる投稿機能](https://qiita.com/japwork/items/8dfb52121036791ac4fb)
- [投稿の編集機能（更新、削除）](https://qiita.com/japwork/items/e258ccbbe4f48ea5a3b5)

# テーブルの作成

```:ターミナル
$ rails g model Comment user:references post:references comment:string
```
```:ターミナル
$ rails db:migrate
```

# モデルの修正
```rb:app/models/user.rb
has_many :comments, dependent: :destroy
```
```rb:app/models/post.rb
has_many :comments, dependent: :destroy
```

<details><summary>補足</summary>
userは複数のCommentモデル、postは複数のCommentモデルを保有するため、
has_many。
またuser、postがなくなった時はcommentも残す必要はないため、
dependent: :destroy。</details>
# コントローラーの作成

```:ターミナル
$ rails g controller comments create destroy
```

```rb:app/controllers/comments_controller.rb
class CommentsController < ApplicationController
  def create
    @post = Post.find(params[:post_id])
    @comment = @post.comments.new(comment_params)
    @comment.user_id = current_user.id
    if @comment.save
      redirect_to request.referer
    else
      @post_new = Book.new
      @comments = @post.comments
      redirect_to new_post_path
    end
  end

  def destroy
    @post = Post.find(params[:post_id])
    @comment = Comment.find(params[:id])
    @comment.destroy
    redirect_to request.referer
  end

  private

  def comment_params
    params.require(:comment).permit(:comment)
  end
end

```

```rb:app/controllers/posts_controller.rb
  def show
    @post = Post.find(params[:id])
    @comment = Comment.new
    @comments = @post.comments
  end
```
# ルーティングの修正
```rb:config/routes.rb
  resources :posts, except: [:index] do
    resources :comments, only: [:create, :destroy]
  end
```

<details><summary>補足１</summary>
上記記述はネストさせています。
ネストについては[こちら](https://qiita.com/chopesu_se/items/c7362380865cf978b158)がわかりやすかったです。</details>
<details><summary>補足２</summary>
exceptは除くという意味なので、index以外のアクションを定義しています。</details>
# viewsの変更
```erb:app/views/show.html.erb
<h1>Posts#show</h1>
<span>現在ログイン中のユーザー：<%= current_user.name %></span>

<table>
  <thead>
    <tr>
      <th>投稿者名</th>
      <th>タイトル</th>
      <th>本文</th>
      <th></th>
      <th></th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><%= @post.user.name %></td>
      <td><%= @post.title %></td>
      <td><%= @post.body %></td>
      <td><%= link_to "編集", edit_post_path(@post) %></td>
    </tr>
  </tbody>
</table>

<%= form_for [@post, @comment] do |f| %>
  <%= f.text_area :comment, size: "40x5" %>
  <%= f.submit '送信', class: "btn-sm btn-primary" %>
<% end %>

<table>
  <thead>
    <tr>
      <th>コメント投稿者</th>
      <th>コメント内容</th>
    </tr>
  </thead>
  <tbody>
    <% @comments.each do |comment| %>
      <tr>
        <td><%= comment.user.name %></td>
        <td><%= comment.comment %></td>
        <td><%= link_to "削除", post_comment_path(@post, comment), method: :delete %></td>
      </tr>
    <% end %>
  </tbody>
</table>
```

```erb:app/views/new.html.erb
<table>
  <thead>
    <tr>
      <th>投稿者名</th>
      <th>タイトル</th>
      <th>本文</th>
      <th></th>
      <th></th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <% @posts.each do |post| %>
      <tr>
        <td><%= post.user.name %></td>
        <td><%= post.title %></td>
        <td><%= post.body %></td>
        <td><%= link_to "詳細", post_path(post) %></td>
        <td><%= link_to "編集", edit_post_path(post) %></td>
        <td><%= link_to "削除", post_path(post), method: :delete %></td>
      </tr>
    <% end %>
  </tbody>
</table>
```

目標完成。