【Ajax通信】非同期通信でのコメント削除機能
おはようございます。
今日は前回記事を書いたコメント投稿機能に削除機能をAjax通信により実装を行っていきます。
初心者コードで恐縮ですが、簡単にまとめていきたいと思います。
【Ajax通信】非同期でのコメント機能の実装 - さかいの気ままにプログラミング日記
実装までの流れ
① viewに削除ボタンをつくる
② JavaScriptで削除ボタンを押したときコメントidをコントローラーに送信する
③ controllerで受け取ったidのコメントをdestroyする
④ JavaScriptでコメントのHTMLを削除する
① viewに削除ボタンをつくる
まずはビューに削除ボタンを作っていきます。
.comment__box .comment__contents - @comments.each do |comment| .comment__posted{data: {comment_id: "#{comment.id}"}} .comment__posted__information .comment__user__nickname = comment.user.nickname .comment__post__time = comment.created_at.strftime("%Y年%m月%d日 %H:%M") .comment__posted__box .comment__posted__content = comment.content - if current_user.id == comment.user_id %button.comment__delete__button %i.far.fa-trash-alt
.comment__posted{data: {comment_id: "#{comment.id}"}}
投稿されたコメントの識別をするためにカスタムデータ特性を追加しています。hamlの記法では文字列の中に#{}で囲うことで変数を使用することができます。
- if current_user.id == comment.user_id
コメント削除はログイン中のユーザーとコメントしたユーザーが一致したときのみ行えるようにします。
JavaScriptで削除ボタンを押したときコメントidをコントローラーに送信する
$(document).on('click', '.comment__delete__button', function(){ var comment_data_id = $(this).parent().parent().data("comment-id") var url = "/events/" + gon.event.id + "/set_lists/" + gon.set_list.id + "/comments/" + comment_data_id $.ajax({ url: url, type: "DELETE", data: comment_data_id, datatype: "json" })
$(document).on('click', '.comment__delete__button', function(){
ユーザーがコメントを送信した直後でも削除ができるように(コメント投稿後にページ遷移することなく削除ボタンを押した場合)、セレクタの取得は$(document).on(~~ で記載するようにしています。
var comment_data_id = $(this).parent().parent().data("comment-id")
削除するコメントidを取得しています。.data("comment-id")では①で追加したカスタムデータ属性を取得しています。このカスタムデータ特性はコメントidと紐付いているので、削除ボタンを押したコメントを削除することができるというロジックになります。
var url = "/events/" + gon.event.id + "/set_lists/" + gon.set_list.id + "/comments/" + comment_data_id
遷移させるurlを指定しています。今回はルーティングをネストさせているので複雑ですが、gonのGemを使いながら記載しています。gonはコントローラーで定義したインスタンス変数をJavaScriptで使えるようにしてくれるGemですごく便利で簡単に実装できるのでよく使っています。gonの導入の仕方は下記事に乗せておきます。
【gem gon】Railsで定義した変数をさくっとJavascriptで使う - Qiita
③ controllerで受け取ったidのコメントをdestroyする
次にコントローラーに処理を書いていきます。
def destroy @comment = Comment.find(params[:id]) @comment.destroy respond_to do |format| format.json { render json: @comment.id } end end
④ JavaScriptでコメントのHTMLを削除する
Ajax通信が成功したときの処理を書いて終了です。
.done(function(comment_id){ $('[data-comment-id = '+ comment_id + ']').remove(); })