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) ======================
