【Rails】SNSアプリのコメント削除機能の実装

参考 URL
https://qiita.com/takahisa_s/items/e6d9713eb9dc0f85f66d
参考も何も理解するには上記の記事を見るだけで十分なのですが、自分用の備忘録として今回の記事を作成いたします。

#前提
私の書いたコメント作成機能の記事の続きです。
https://qiita.com/Zhongcun/items/42b15f045a363ec82af5

また、【削除できるコメントは自分が作成したコメントのみ】とします。

#ルーティング

```ruby:routes.rb
resources :microposts, only: [:create, :destroy, :show] do
  resources :comments, only: [:create, :destroy]
end
```

#コントローラー
コメント削除ボタンに関わることなので、micropostのコントローラの記述もしておきます。

```ruby:microposts_controller.rb
  def show
    @micropost = Micropost.find(params[:id])
    @comments = @micropost.comments.includes(:user)
    @comment = @micropost.comments.build # form_with 用
  end
```
省略されている部分に関しては先述の[前回の記事](https://qiita.com/Zhongcun/items/42b15f045a363ec82af5)を参考にお願いします。

```ruby:comments_controller.rb
class CommentsController < ApplicationController
  before_action :require_user_logged_in
  before_action :correct_user, only: [:destroy]
  
  def create
    @micropost = Micropost.find(params[:micropost_id]) 
    @comment = @micropost.comments.build(comment_params)
    @comment.user_id = current_user.id
　　　〜〜〜 
　　　省略
　　　〜〜〜
　end

  def destroy
    @comment.destroy
    flash[:success] = '投稿へのコメントを削除しました。'
    redirect_back(fallback_location: root_path)
  end
  
  private
  
  def comment_params
    params.require(:comment).permit(:content)
  end
  
  def correct_user
    @comment = current_user.comments.find_by(id: params[:id])
    unless @comment
      redirect_to root_url
    end
  end
end
```
`def destroy`で`@comment`を定義しなくていい理由は、createで定義した`@comment`を使いまわしているためです。
`redirect_back`とありますが、投稿の詳細ページでのみコメントを削除するため投稿詳細ページに戻るだけです。

また`def correct_user`により、削除できるコメントは自分がしたコメントのみになります。

#コメント削除のルーティングの確認

```ターミナル
$ rails routes
```
コメント削除に必要なPrefixと渡すべき値を確認します。

```
micropost_comment DELETE /microposts/:micropost_id/comments/:id(.:format)　comments#destroy
```

削除するには`micropost_comment_path`を使い、
特定のmicropostとcommentのidを渡す必要があります。

#ビューファイル
###投稿詳細ページ
このファイルの`@micropost`だけを心に留めておいてください。

```erb:microposts/show.html.erb
<ul class="list-unstyled">
  <li class="media mb-3">
    <img class="mr-2 rounded" src="<%= gravatar_url(@micropost.user, { size: 50 }) %>" alt="">
    <div class="media-body">
      <div>
        <%= link_to @micropost.user.name, user_path(@micropost.user) %> <span class="text-muted">posted at <%= @micropost.created_at %></span>
      </div>
      <div>
        <p><%= @micropost.content %></p>
      </div>
      <div class="btn-group">
        <% if current_user == @micropost.user %>
          <%#=投稿詳細ページで投稿を削除するとid見つからないエラー発生 link_to "Delete", @micropost, method: :delete, data: { confirm: "You sure?" }, class: 'btn btn-danger btn-sm' %>
        <% end %>
      <%= render 'favorites/favorite_button', micropost: @micropost %>
      </div>
    </div>
  </li>
</ul>

<%# コメント入力フォームのパーシャル %>
<%= render 'comments/form', micropost: @micropost %>

<%# コメント一覧のパーシャル %>
<%= render 'comments/comments', micropost: @micropost %>
```

###コメント一覧のパーシャル(ここにコメント削除ボタン実装)
```erb:
<%# コメント一覧用 %>
<ul class="list-unstyled">
  <% @comments.each do |comment| %>
    <li class="media mb-3">
      <img class="mr-2 rounded" src="<%= gravatar_url(comment.user, { size: 50 }) %>" alt="">
      <div class="media-body">
        <div>
          <%= link_to comment.user.name, user_path(comment.user) %> <span class="text-muted">posted at <%= comment.created_at %></span>
        </div>
        <div>
          <p><%= comment.content %></p>
        </div>
        <div class="btn-group">
          <% if current_user == comment.user %>
<%# ここにコメント削除ボタン %>
            <%= link_to "Delete", micropost_comment_path(@micropost, comment), method: :delete, data: { confirm: "You sure?" }, class: 'btn btn-danger btn-sm' %>
          <% end %>
        </div>
      </div>
    </li>
  <% end %>
  <%#= paginate comments %>
</ul>
```

削除するにはURLに`micropost_comment_path`を使い、
`@micropost, comment`の2つを渡す必要があります。

`@micropost`はコントローラのshowで定義されているもので、
`comment`はコメント一覧パーシャルの
`<% @comments.each do |comment| %>`の`|comment|`を基にしています。

何か間違っていることがあれば、コメントや編集リクエストをいただけると幸いです。