【フリマアプリ】商品詳細ページのコメント機能〜コード全文〜

```ruby:items/show.html.haml
          -# ===================================
          -# コメント全体
          -# ===================================
          .commentBox
            .comment_list
              - if user_signed_in?
                - @commentALL.each do |comment|
                  - if comment.user_id == current_user.id   
                    -#   ===================================
                    -#   コメントユーザーとログインユーザーが同一の場合  
                    -#   ===================================
                    .comment_Me.comment_one_block{data:{index: comment.id}}                   
                      - if comment.delete_check == 1   # 削除済の場合
                        .comment_content
                          = render 'items/template_comment/comment_delete_restore_btn',comment: comment 
                      - else   # 削除されていない場合
                        .comment_content
                          = comment.comment
                          .comment_create_at
                            = comment.created_at.strftime("%Y年%m月%d日 %H時%M分")
                          - if comment.item.seller == current_user
                            .comment_delete.me_pre_delete{data:{index: comment.id}}     
                              = link_to '削除する', comment_path(comment.id) ,method: :patch
                      = render 'items/template_comment/comment_name',comment: comment                    
                  - else 
                    -#   ===================================
                    -#   コメントユーザーとログインユーザーが異なる場合の場合  
                    -#   ===================================
                    .comment_Other.comment_one_block{data:{index: comment.id}}    
                      = render 'items/template_comment/comment_name',comment: comment               
                      - if comment.delete_check == 1   # 削除済の場合
                        .comment_content_other
                          = render 'items/template_comment/comment_delete_restore_btn',comment: comment               
                      - else    # 削除されていない場合
                        .comment_content_other
                          = comment.comment
                          .comment_create_at
                            = comment.created_at.strftime("%Y年%m月%d日 %H時%M分")
                          - if comment.item.seller == current_user   # 出品者とログインユーザーが等しい場合
                            .comment_delete.other_pre_delete{data:{index: comment.id}}     
                              = link_to '削除する', comment_path(comment.id) ,method: :patch
            -#   ===================================
            -#   投稿フォーム
            -#   ===================================
            - if user_signed_in?              
              = form_with model:@comment ,class:"new_comment", local: true do |f|
                = f.text_area :comment,id: "comment_body",wrap: "soft"
                = f.hidden_field :item_id, value: @item.id

                %p.noticeMsg
                  相手のことを考えて丁寧なコメントをこころがけましょう。
                  %br/
                  不快な言葉遣いなどは利用制限や退会処分となることがあります。
                %br/
                %button.commentBtn{name: "button", type: "submit"}
                  %i.fa.fa-comment
                  コメントする
```

```haml:_comment_delete_restore_btn.html.haml
出品者によりこのコメントは削除されました。
- if comment.item.seller == current_user    # 出品者とログインユーザーが等しい場合
  .comment_restore{data:{index: comment.id}} 
    = link_to "復元する",restore_comment_path(comment.id)
  .comment_delete.complete_delete{data:{index: comment.id}}     
    = link_to '完全に削除する', comment_path(comment.id) ,method: :delete,class: "complete_delete"
```

```haml:app//_comment_delete_restore_btn.html.haml
.comment_user_name
  = comment.user.nickname
  - if comment.user ==  comment.item.seller  # コメントユーザーと出品者が同じ場合
    .seller_display
      出品者
```

```ruby:comments_controller.rb
class CommentsController < ApplicationController
  
  before_action :set_comment, only: [:update,:destroy,:restore]
  before_action :check_user, only: [:update,:destroy,:restore]

  def create
    @comment = Comment.new(comment_params)
    @seller_of_item = User.find(@comment.item.seller_id)
    if @comment.save
        respond_to do |format|
        format.json
      end
    else
      flash[:alert] = "保存できていません"
      redirect_to item_path(params[:id])
    end
  end

  def update
    @comment.update(delete_check:1)
  end

  def destroy
    @comment.destroy
  end

  def restore
    @comment.update(delete_check:0)
    @seller_of_item = User.find(@comment.item.seller_id)
    respond_to do |format|
    format.json
  end
end

private
  def comment_params
    params.require(:comment).permit(:comment,:item_id).merge(user_id: current_user.id)
  end

  def set_comment
    @comment = Comment.find(params[:id])
  end

  def check_user
    unless @comment.item.seller == current_user
      flash[:alert] = "その操作はできません"
      redirect_to root_path
    end
  end
end
```

```javascript:comment.js
$(function(){
// ===================================
// 新規コメント表示用・自分のコメント復元用 
// ===================================
  function new_comment(comment_data){
    var HTML_content_time = 
      `
      <div class="comment_Me comment_one_block" data-index=${comment_data.id}>
        <div class="comment_content">
          ${comment_data.comment}
          <div class="comment_create_at">
            ${comment_data.created_at}
          </div>
      `
    var HTML_deleteBtn =  
        `
        <div class="comment_delete me_pre_delete" data-index=${comment_data.id}>
          <a rel="nofollow" data-method="patch" href="/comments/${comment_data.id}">削除する</a>
        </div>
        `
    var HTML_nickname =
        `
        </div>
        <div class="comment_user_name">
          ${comment_data.user_nickname}
        `
    var HTML_sellerMark =
        `
          <div class="seller_display">
          出品者
          </div>
        `
    var HTML_endDiv =
      `
        </div>
      </div> 
      `
    if (comment_data.item_seller.id == comment_data.user_id){
        // 出品者とコメントしたユーザーが等しい場合
      var html = HTML_content_time + HTML_deleteBtn + HTML_nickname + HTML_sellerMark + HTML_endDiv
    }else{
       // 出品者とコメントしたユーザーが異なる場合
      var html = HTML_content_time + HTML_nickname + HTML_endDiv
          };

    return html;
  };
// ===================================
// 他人のコメント復元用 
// ===================================
  function restore_other_comment(comment_data){
    var html = 
    `
    <div class="comment_Other comment_one_block" data-index=${comment_data.id}>
      <div class="comment_user_name">
      ${comment_data.user_nickname}
      </div>
    
      <div class="comment_content_other">
        ${comment_data.comment}
        <div class="comment_create_at">
          ${comment_data.created_at}
        </div>
        <div class="comment_delete other_pre_delete" data-index=${comment_data.id}>
          <a rel="nofollow" data_method="patch" href="/comments/${comment_data.id}">削除する</a>
        </div>
      </div>
    </div>
    `
  return html;
  };

// ===================================
// 仮削除表示用
// ===================================

function PLEdelete(index){
  var html = 
  `
  出品者によりこのコメントは削除されました。
  <div class="comment_restore" data-index=${index}>
    <a href="/comments/${index}/restore">復元する</a>
  </div>
  <div class="comment_delete complete_delete" data-index=${index}>
    <a class="complete_delete" rel="nofollow" data-method="delete" href="/comments/${index}">完全に削除する</a>
  </div>
  `

return html;
};


// ===================================
// コメント作成した場合
// ===================================
  $('.new_comment').on('submit', function(e){
    e.preventDefault()
    var formData = new FormData(this);
    var url = $(this).attr('action');
    $.ajax({
      url: url,
      type: "POST",
      data: formData,
      dataType: 'json',
      processData: false,
      contentType: false
    })
  .done(function(comment_data){
    var html = new_comment(comment_data);
    $(".comment_list").append(html)
    $('#comment_body').val("");
    $('.comment_list').animate({ scrollTop: $('.comment_list')[0].scrollHeight});
  })
  .fail(function() {
    alert("メッセージ送信に失敗しました");
  });
});

// ===================================
// 復元した場合
// ===================================
$(".comment_list").on('click',".comment_restore",function(e){
  e.preventDefault()
  var index = $(this).data("index")
  var url =`/comments/${index}/restore`
  $.ajax({
    url: url,
    type: "get",
    dataType: 'json',
  })
  .done(function(comment_data){
    if (comment_data.item_seller.id == comment_data.user_id){   // 出品者とコメントユーザーが同じ場合
      var html = new_comment(comment_data);
      $(`.comment_one_block[data-index=${index}]`).replaceWith(html)
    }else{    // 出品者とコメントユーザーが異なる場合
      var html = restore_other_comment(comment_data);
      $(`.comment_one_block[data-index=${index}]`).replaceWith(html)
    }
  })
  .fail(function() {
    alert("メッセージ送信に失敗しました");
  });
});
  

// ===================================
// 自分のコメントを仮削除した場合
// ===================================

$(".comment_list").on('click',".me_pre_delete",function(e){
  e.preventDefault()
  var index = $(this).data("index");
  var content =  $(`.comment_one_block[data-index=${index}]`).find(".comment_content");
  content.empty();
  content.append(PLEdelete(index));
});

// ===================================
// 他人のコメントを仮削除した場合
// ===================================

$(".comment_list").on('click',".other_pre_delete",function(e){
e.preventDefault()
var index = $(this).data("index");
var content =  $(`.comment_one_block[data-index=${index}]`).find(".comment_content_other");
content.empty();
content.append(PLEdelete(index));
});

// ===================================
// 完全削除した場合
// ===================================
$(".comment_list").on('click','.complete_delete',function(e){
  e.preventDefault()
  var index = $(this).data("index");
  $(`.comment_one_block[data-index=${index}]`).remove();
  });

})
```