Rails 5の目玉機能「Action Cable」で双方向通信を実装(2)
サンプルコードで学ぶRuby on Rails 5実践入門 第8回
ダウンロード サンプルファイル (186.7 KB)
前回はRails 5目玉機能の1つであるAction Cableのサンプルアプリ実装を通してAction Cableへの理解を深めました。今回は引き続きAction Cableのサンプルアプリを拡張して、発言をデータベースに保存できるようにし、会員登録機能と関連付けを行います。
発言をデータベースに保存する
まずは発言をデータベースに保存できるようにします。発言をDB保存するにあたり、まずはサーバー側で発言を保存した後、非同期でクライアント側にブロードキャストするよう修正します。なお、この時点では発言するのにログインは必須としていないので、ユーザーIDをchat_messagesテーブルに保存する処理は入れず、後から処理を加えます。
修正の手順をまとめると以下の通りです。
- チャネルからモデルを生成するように修正
- モデルのデータ保存をチャネル側で行うように修正
- モデルが保存されてから非同期でブロードキャストするジョブを作成
- 初期アクセス時に保存した発言が表示されるように修正
チャネルからモデルを生成するように修正
まず、チャネル内で直接ブロードキャストしていた箇所を、モデルを生成するためspeakメソッドをリスト1の通りに修正します。
class ChatMessageChannel < ApplicationCable::Channel
…(中略)…
def speak(data)
ChatMessage.create! body: data['message']
end
end
モデルの生成にはcreate!メソッドを使用します。create!メソッドは何らかの理由でレコード生成に失敗した場合に例外を投げるメソッドです。data['message']で受け取った発言をchat_messagesテーブルのbodyカラムにセットしてレコードを生成します。
モデルの修正
ブロードキャストする処理をモデルが生成した後のタイミングで行うよう、リスト2の通りに修正します。
class ChatMessage < ApplicationRecord
after_create_commit { ChatMessageBroadcastJob.perform_later self }
end
after_create_commitメソッドは、ActiveRecordのcreateまたはcreate!メソッドが呼び出されてデータベースへのコミットが正常終了した後に、{}で指定したブロックが後処理として呼び出します。ChatMessageBroadcastJobは、次の手順で作成するジョブでperform_laterメソッドを通じて呼び出すことができます。引数にself、つまりモデル自身を渡しています。
非同期でブロードキャストするジョブの作成
ジョブとは、Rails 4.2から導入された非同期処理の仕組みのことで、Active Jobと呼ばれます。ジョブファイルの生成は、Railsが提供するジェネレーターコマンドを使用します。
bin/rails g job ChatMessageBroadcast
↓
Running via Spring preloader in process 83621
invoke test_unit
create test/jobs/chat_message_broadcast_job_test.rb
create app/jobs/chat_message_broadcast_job.rb
ジェネレーターコマンドで自動生成されたファイルを確認してみましょう。
class ChatMessageBroadcastJob < ApplicationJob
queue_as :default
def perform(*args)
# Do something later
end
end
queue_asメソッドは、ジョブを実行するキューの名前を指定するものです。呼び出し側でperform_laterメソッドによってジョブが呼び出されると、performメソッドに記述された処理が実行されます。このジョブが実行されたら、ブロードキャストする処理をperformメソッドに記述しましょう。
class ChatMessageBroadcastJob < ApplicationJob
…(中略)…
def perform(chat_message)
ActionCable.server.broadcast 'chat_message_channel', message: chat_message.body
end
end
追加したブロードキャストする処理は、元々チャネルのspeakメソッドで定義していた処理のままです。
初期アクセス時に保存した発言が表示されるように修正
次に、保存した発言をデータベースから取得して表示されるように修正します。まずはコントローラーをリスト5の通りに修正しましょう。
class ChatMessagesController < ApplicationController
def index
@chat_messages = ChatMessage.all
end
end
ChatMessage.allで全ての発言をchat_messagesテーブルから取得して、インスタンス変数@chat_messagesに代入してビューで使用できるようにします。
次にビューをリスト6の通りに修正しましょう。
<div id='chat_messages'>
<% @chat_messages.each do |chat_message| %>
<div><%= chat_message.body %></div>
<% end %>
</div>
…(中略)…
全ての発言が代入されている@chat_messagesをeachでループして、1つ1つの発言をdiv要素で囲んで表示しています。
動作確認
これで、一通り発言をデータベースに格納した後にブロードキャストする修正が完了しました。「http://localhost:3000/chat_messages/index」にアクセスして動作確認をしてみましょう。
この記事は参考になりましたか?
- サンプルコードで学ぶRuby on Rails 5実践入門連載記事一覧
-
- Rails 5のAPIモードを使ってAPIを実装
- Rails 5の目玉機能「Action Cable」で双方向通信を実装(2)
- Rails 5.1でReact.js連携アプリを構築してみよう
- この記事の著者
-
WINGSプロジェクト 竹馬 力(チクバ ツトム)
< WINGSプロジェクト について> 有限会社 WINGSプロジェクト が運営する、テクニカル執筆コミュニティ(代表 ...
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
