FreeCamp

ActionCable リアルタイムチャット(jQuery)

Railsアプリケーションでリアルタイムチャットを作成する時に
必ずと言っていいほど出てくるのが、CoffeeScriptですよね。
とりあえずコピペしてできたからいいや、という考えですとアプリケーションをカスタマイズする際に必ずつまづきます。
CoffeeScript→jQueryは容易に書き換えることが可能なので、
今回の記事ではRailsアプリケーションにjQueryを用いてリアルタイムチャットを実装していきます。

※なお、今回はモデルを作成しないため、データは保存しません。
リロードすると投稿消えます。

見出し

  1. ActionCable導入
  2. CoffeeScript→jQuery
  3. 完成コード

1. ActionCable導入

$ rails new sample_app
$ cd sample_app
$ rails g controller home top

ルートパスの設定をします。

...編集
get 'home/top'
↓
root 'home#top'

jQueryを利用できるようにします。

...追加
gem 'jquery-rails'
$ bundle install
...追記
//= require 'jquery'

ここからActionCableの設定をしていきます。
まずは投稿フォームの作成。

...追記
<input type="text" class="post">

Railsのコマンドでchannelというのを作成していきます。
channelは概念的にはcontrollerと同じようなもので、フロントからのリクエストを受け取り、レスポンスを返します。

rails g channel post create

2. CoffeeScript→jQuery

app/channels/post_channel.rbとapp/javascript/channels/post.coffeeが作成されたと思います。
このpost.coffeeを消し、同じ階層にpost.jsを作成しましょう。

const app = App.cable.subscriptions.create('PostChannel', {
  connected: function(data) {
  },
  disconnected: function(data) {
  },
  received(data) {
    $('body').append('<p>' + data["data"] + '</p>');
  }
})

$(function() {
  $(document).on('keypress', '.post', function(e) {
    if (e.keyCode === 13) {
      app.perform("create", {data: $('.post').val()});
      $('.post').val('');
    }
  })
})

app.perform(“create”, {data: $(‘.post’).val()});でサーバー側のcreateアクションを呼んでいます。
また、received(data)でサーバーからレスポンスがあった際にデータを受け取ります。
次にchannel側の設定もしていきます。

class PostChannel < ApplicationCable::Channel
  def subscribed
    stream_from "post_channel"
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end

  def create(data)
    ActionCable.server.broadcast 'post_channel', data
  end
end

ActionCable.server.broadcast ‘post_channel’, dataでフロントに値を返しています。
これでリアルタイムチャット(データの保存はなし)ができました。
二つブラウザを開き、どちらもhttp://localhost:3000でアクセスし、投稿フォームから投稿してみましょう。
片方で投稿した内容がどちらのブラウザにも反映されたでしょうか。

3. 完成コード

https://github.com/ssshhhooota/rails_realtimechat