概要
この記事はAction Cableでリアルタイムチャットアプリの作成方法 (Rails 5.1.4にて)(その2)グループ別チャンネルの作成!!続きである。
今回は、投稿データをActionCableを使用してリアルタイムで消すという機能を実装したい。
誰かが、投稿の削除ボタンを押すと、ActionCableによってすべてのユーザーの画面から非同期通信でリアルタイムに投稿が削除される。
まず、すべての投稿に投稿idを個々の投稿divのidとして紐づける。
そして、ActionCableでそのidを送信し、それを使用して、jqueryのremove()を利用して、表示を消し、同時にdestroyでデータベースからも消す。
環境
Ruby2.2.4
Rails 5.1.4
手順
1.投稿idをdivのidとして紐づけと削除ボタンの追加
通常の表示画面とActionCableのテンプレートの両方を編集する。
idの紐づけ:<div class="posts-index-item" id="<%=post.id%>">
削除ボタン: <button id="<%=post.id%>" class="delete-btn">削除</button>
削除アクションのトリガーのためにclassをdelete-btnとする。
<div class="container">
<%@posts.each do |post|%>
<%user = User.find_by(id: post.user_id)%>
<div class="posts-index-item" id="<%=post.id%>">
<%if post.user_id%>
<div class="post-user-name">
<img src="<%="/user_images/#{user.image_name}"%>" alt="">
<%=link_to("#{user.name}","/users/#{user.id}/show")%>
</div>
<%end%>
<%=link_to(simple_format(post.content), "/posts/#{post.id}")%>
<button id="<%=post.id%>" class="delete-btn">削除</button>
</div>
<%end%>
2.deleteチャンネル・アクションの作成
その1と同様の手順でチャンネルとアクションを作成する。
$rails g channel delete delete
3. delete.coffeeの編集(クライアントサイド)
先ほど作成した削除ボタンをトリガーにしてdelete event.target.idで投稿idをidから取得しdeleteメゾットに渡す。
それによってdelete_channelのdeleteアクションを呼び、その際にもidを渡す。
(...)
delete: (id)->
@perform 'delete', id: id
$(document).on 'click', '.delete-btn', (event) ->
App.delete.delete event.target.id
4.delete_channelの編集(サーバーサイド)
delete.coffee(クライアントサイド)から受け取ったidをブロードキャストするのと同時に、投稿をデータベースからも削除する。
def delete(data)
ActionCable.server.broadcast 'delete_channel', id: data['id']
post = Post.find_by(id: data['id'])
post.destroy
end
5.再度delete.coffeeの編集(クライアントサイド)
ブロードキャストされたものを受け取った時の処理を書く。
受け取ったidをjqueryで使えるように変換し、それを使いremove()で投稿を削除する。
received: (data) ->
# Called when there's incoming data on the websocket for this channel
# 該当投稿の削除
id = "#" + data['id']
console.log(id)
$(id).remove()
完成!!!