Railsでの製作Tips

Rails5でAjax処理をActionCableを使ってリアルタイム同期化

投稿日:

はじめに

画面遷移をせずに一部を書き換えるAjax処理をしている部分をRails5のActionCableでリアルタイム化してみた.
通常、RailsでのAjax処理は次の遷移をたどることが多いと思う.

formからremote: trueで投稿

コントローラーのCreateアクションで保存

create.js.coffeeテンプレートでjQueryを使って画面の一部を書き換え

今回は、ActionCableを使って、ほかの人の見ている画面もリアルタイムに書き換える

準備として、チャンネルを購読して、ストリームで分配する

formからremote: trueで投稿

コントローラーのcreateアクションで保存

broadcast_toでストリームに通知

コンシューマーのreceivedメソッドで、jQueryを使って画面の一部を書き換え

サンプル掲示板

モデルはPostとMessage.PostとMessageとの関係は1対多.
また、DeviseでUserのみ投稿できるように制限している.
Postのshow.html.erb内でPostと関連するMessageを表示し、formからremote: trueで投稿して関連するメッセージを書き換えている.
今回関連する処理だけ抜き出すと次のとおり.

show.html.erb

messages_controller.rb

create.js.coffee

_message.html.erb

ActionCableでリアルタイム化

generate

これで、cable.jsとjavascripts/channels/message.coffeeとchannels/message_channel.rbが生成される.

今のバージョンではredisを準備しなくても、簡単にActionCableを試すことができる.

config/cable.ymlで設定することができる.

cable.jsでは、コンシューマーを作成している.クライアント側.
ここは変える必要がないのでそのまま.

チャンネルを購読して、ストリームで分配する

ActionCableでは、チャンネルは論理的な作業単位をカプセル化するということなので、リアルタイム化したい通信の種類ごとに作成すればよい.
そして、クライアント側のコンシューマーから、チャンネルを購読(subscribe)する.
サーバー側では、購読者をストリームという機能で、配信するコンテンツを分配(ルーティング)する.
ここでは、同じPostを見ている人にメッセージの更新を配信したいので、ポストごとにストリームで分配する.

message.coffee

購読(subscription)をcreateする.createは単にStringを引数にすることもできるが、連想配列を引数にとることもできる.
その際にchannelというキーは必須になる.その他のデータはparamsとして、サーバー側で使うことができる.
今回は、post_idを投げたかったので、関数にして、viewから直接呼び出すことにした.

show.html.erb

message_channel.rb

サーバー側では、subscribedというメソッドでストリームを作成する.
stream_fromというメソッドで一定のストリームを作成することもできる.
その際に、ストリーム名をpost_idに従って変えればよい.(コメントした部分)
けど、stream_forというメソッドを使えば、モデルに関連するストリームを作成することができる.
こちらの方が簡単.

createアクションからbroadcast_toで発火

今回は、createアクションが成功したら、発火する.
どうもbroadcastメソッドはストリームのルーティングを無視する(全部に配信する)みたいなので、broadcast_toを使う.
broadcastメソッドは、ActionCable.server.broadcastだったけど、broadcast_toメソッドは、MessageChannel.broadcast_toなので注意が必要.

receivedメソッド

broadcast_toしたデータをdataで取り出す.
rubyと違って、[]内はシンボルでなくStringを使うので注意.
今回はrenderしたhtmlなので、そのままjQueryオブジェクトにした.

Done!

rails5になってActionCableのあつかいがますます簡単になった.
今回、次のページを参考にした.

Action Cable の概要
Rails5のActionCableで簡易チャットの作成 ~モデルに応じたチャンネルを聴講する方法~
ActionCable: How to use dynamic channels

-Railsでの製作Tips
-,

執筆者:

関連記事

Rubyのメソッドの引数について

By: Jared Tarbell – CC BY 2.0 目次1 HackerRank2 メソッドの引数3 デフォルト値4 *をつけた可変長引数(rest引数)5 キーワード引数6 ** …

railsのpathヘルパーでスラッシュの代わりにピリオドになっちゃうのでrails consoleでいろいろ試した

By: Nicolas Raymond – CC BY 2.0 目次1 問題2 解決3 pathとurlのヘルパーのあれこれ 問題 次のような環境で [crayon-5887c35b7f5 …

RailsのフォームにjQuery UIのSliderを使う

By: woodleywonderworks – CC BY 2.0 目次1 jQuery UI Slider2 ライブラリを読み込む3 コード4 できた jQuery UI Slider …

Railsでdate_fieldにjquery uiのdatepickerを使おうとしたらchromeのdatepickerとかち合ってしまったとき

By: Randy Heinitz – CC BY 2.0 text_fieldにしとけば、jQuery UI datepickerは使える. [crayon-5887c35b7fa653 …

Redmine3でのテストあれこれ〜minitest

By: Pedro Ribeiro Simões – CC BY 2.0 目次1 RSpec or Minitest?2 Minitestの基本とか3 Redmine本体のユニットテストを …