Action Cableのおさらい
本連載の第1回でも紹介しましたが、Rails 5の目玉機能であるAction Cableは、Rails上でWebSocketによる双方向通信を簡単に実現する新しい機能です。WebSocket(ウェブソケット)とは、サーバーを介してWebブラウザ間で双方向通信を行う仕組みです。これまでWebSocketをRails上で実現するには、複雑な処理を自前で書く必要がありました。Rails 5で新たに用意されたAction Cableを使うと、驚く程簡単に双方向通信が実現できます。Action Cableでは以下の機能が用意されています。
主な機能 | 機能概要 | 実装の配置箇所 |
---|---|---|
コネクション | WebSocket通信をサーバーとクライアントで接続する仕組み | app/channels/application_cable/connection.rbとして提供 |
チャネル | WebSocketを使う上で必要となるサーバー側の仕組み | app/channels配下にApplicationCable::Channelを継承して利用 |
クライアント | WebSocketを使う上で必要となるクライアント側の仕組み。JavaScript/CoffeeScriptで提供 | app/assets/javascripts/channels配下に配置 |
ジェネレーター | rails g channelコマンドによるチャネル・クライアントのコードひな型自動生成 | - |
開発するチャットアプリ(1)
今回はAction Cableの機能を利用して、リアルタイムチャット機能を実装します。この機能の要件をまとめると以下の通りです。
- 発言するにはユーザー登録が必要
- 各クライアントのブラウザで入力ボックスに文字を入れ、エンターキーを押下すると発言できる
- 発言はチャットに接続している各クライアントに対して即座に配信される
- 発言はデータベースに保存される
これらの要件を満たすチャットアプリを以下の手順で開発していきます。
- チャット用コントローラーの作成
- チャット用モデルの作成
- チャット用チャネルの作成
- 入力フォームの作成
- 動作確認
- 発言をデータベースに保存できるようにする
- 発言を登録済みユーザーに限定させる
チャット用コントローラーの作成
まず、チャット用のコントローラーを作成します。以下のジェネレートコマンドでコントローラーを作成します。なお、チャット表示用の画面のみで必要となるため、index
アクションだけを指定します。
bin/rails g controller ChatMessages index
↓
Running via Spring preloader in process 17041 create app/controllers/chat_messages_controller.rb route get 'chat_messages/index' invoke erb create app/views/chat_messages create app/views/chat_messages/index.html.erb invoke test_unit create test/controllers/chat_messages_controller_test.rb invoke helper create app/helpers/chat_messages_helper.rb invoke test_unit invoke assets invoke coffee create app/assets/javascripts/chat_messages.coffee invoke scss create app/assets/stylesheets/chat_messages.scss
チャット用モデルの作成
次に、チャットメッセージ保存用のモデルを作成します。モデル名はchat_message
、ユーザーIDとメッセージ本文を保存する必要があるので、カラムにuser_id
とbody
を指定します。以下のジェネレートコマンドでモデルを作成しましょう。
bin/rails g model chat_message user_id:integer body:text
↓
Running via Spring preloader in process 17756 invoke active_record create db/migrate/20170317102938_create_chat_messages.rb create app/models/chat_message.rb invoke test_unit create test/models/chat_message_test.rb create test/fixtures/chat_messages.yml
先立ってマイグレーションを実行しておきます。
bin/rails db:migrate
↓
== 20170317102938 CreateChatMessages: migrating =============================== -- create_table(:chat_messages) -> 0.0155s == 20170317102938 CreateChatMessages: migrated (0.0155s) ======================