SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

サンプルコードで学ぶRuby on Rails 5実践入門

Rails 5の目玉機能「Action Cable」で双方向通信を実装(2)

サンプルコードで学ぶRuby on Rails 5実践入門 第8回

  • X ポスト
  • このエントリーをはてなブックマークに追加

 前回はRails 5目玉機能の1つであるAction Cableのサンプルアプリ実装を通してAction Cableへの理解を深めました。今回は引き続きAction Cableのサンプルアプリを拡張して、発言をデータベースに保存できるようにし、会員登録機能と関連付けを行います。

  • X ポスト
  • このエントリーをはてなブックマークに追加

発言をデータベースに保存する

 まずは発言をデータベースに保存できるようにします。発言をDB保存するにあたり、まずはサーバー側で発言を保存した後、非同期でクライアント側にブロードキャストするよう修正します。なお、この時点では発言するのにログインは必須としていないので、ユーザーIDをchat_messagesテーブルに保存する処理は入れず、後から処理を加えます。

 修正の手順をまとめると以下の通りです。

  • チャネルからモデルを生成するように修正
  • モデルのデータ保存をチャネル側で行うように修正
  • モデルが保存されてから非同期でブロードキャストするジョブを作成
  • 初期アクセス時に保存した発言が表示されるように修正

チャネルからモデルを生成するように修正

 まず、チャネル内で直接ブロードキャストしていた箇所を、モデルを生成するためspeakメソッドをリスト1の通りに修正します。

リスト1 app/channels/chat_message_channel.rb
class ChatMessageChannel < ApplicationCable::Channel
…(中略)…
  def speak(data)
    ChatMessage.create! body: data['message']
  end
end

 モデルの生成にはcreate!メソッドを使用します。create!メソッドは何らかの理由でレコード生成に失敗した場合に例外を投げるメソッドです。data['message']で受け取った発言をchat_messagesテーブルのbodyカラムにセットしてレコードを生成します。

モデルの修正

 ブロードキャストする処理をモデルが生成した後のタイミングで行うよう、リスト2の通りに修正します。

リスト2 app/models/chat_message.rb
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

 ジェネレーターコマンドで自動生成されたファイルを確認してみましょう。

リスト3 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メソッドに記述しましょう。

リスト4 app/jobs/chat_message_broadcast_job.rb
class ChatMessageBroadcastJob < ApplicationJob
…(中略)…
  def perform(chat_message)
    ActionCable.server.broadcast 'chat_message_channel', message: chat_message.body
  end
end

 追加したブロードキャストする処理は、元々チャネルのspeakメソッドで定義していた処理のままです。

初期アクセス時に保存した発言が表示されるように修正

 次に、保存した発言をデータベースから取得して表示されるように修正します。まずはコントローラーをリスト5の通りに修正しましょう。

リスト5 app/controllers/chat_messages_controller.rb
class ChatMessagesController < ApplicationController
  def index
    @chat_messages = ChatMessage.all
  end
end

 ChatMessage.allで全ての発言をchat_messagesテーブルから取得して、インスタンス変数@chat_messagesに代入してビューで使用できるようにします。

 次にビューをリスト6の通りに修正しましょう。

リスト6 app/views/chat_messages/index.html.erb
<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」にアクセスして動作確認をしてみましょう。

次のページ
ログインしないとチャットにアクセスできないようにする

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
サンプルコードで学ぶRuby on Rails 5実践入門連載記事一覧

もっと読む

この記事の著者

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本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/10255 2017/07/10 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング