Railsの勉強のために簡単なサービスを作っています。
そこでActionCable機能を利用してみたくなったのですが、しかしバージョンはRails4。
Qiitaでの有用な記事を参考にさせてもらって実装しましたが、時間経過によって変更された部分や、Rails4特有の理由により詰まった所があったので、2016年7月時点で動かす為に必要な事を書いておきます。
環境:
ruby:2.2.3
rails:4.2.5
-
ActionCableの実装基礎知識
http://qiita.com/jnchito/items/aec75fab42804287d71b -
Rail4でのActionCable
http://qiita.com/totzyuta/items/556d1bae65bb918db322
上記に挙げた記事は非常に参考になりました。
作者の方々、ありがとうございます。
本記事はこれらの導入記事があった上での補足情報になります。
#詰まりポイント1: gemの宣言
Rails4での導入記事でのgemfile記述を行うとbundle installでエラーが出てしまいます。
# Gemfile
gem 'actioncable', github: 'rails/actioncable'
↓ 今はこっち
# Gemfile
gem 'actioncable', github: 'rails/actioncable', branch: 'archive'
2016年7月現在では、githubのrails/actioncableはrails/rails/以下に移動しました。
Rails4用のActionCableのソースは今はrails/actioncableのbranchにて公開されています。
#詰まりポイント2: AssetPipeline requireでのモジュール名称
ActionCableはRail4->Rails5でrequireするモジュール名称が変更になりました。
#= require action_cable
↑はRail5 ↓ Rail4はこっち
#= require cable
Rail5での導入を参考にするとrequreには"action_cable"とありますが、 rails4ではrequireには"cable" です。
#詰まりポイント3: Rails4では cable.rb or cable.coffeeのファイル名はダメ
ActionCableを利用するにはブラウザからjavascriptでルームへ接続する命令を書かなければなりません。
そのjavascript命令を記述するファイル名にも注意点があります。
(function () {
this.App || (this.App = {});
App.cable = Cable.createConsumer("/cable");
}).call(this);
↑はRail5ではcable.jsのファイル名はOK ↓ Rail4はダメなのでcable以外の任意のファイル名。
(function () {
this.App || (this.App = {});
App.cable = Cable.createConsumer("/cable");
}).call(this);
Rail5のgithubのREADME.mdなどを見ながら作業を進めると、cable.jsというファイルを作ってそこにルームへの接続命令を書く例が示されています。
しかし、Rails4でrequireするモジュール名が"cable"のため、実装側でcable.js(もしくはcable.coffee)ファイルを作成すると、モジュール側のcable.jsとバッティングします。
ここは素直にcable.js以外のファイル名にしましょう。
#おまけ Webサーバーは一つで気軽にActionCableを試す場合
ActionCableはActionCable機能を利用するサービスのアプリケーションサーバーとは、別にマルチスレッド対応のアプリケーションサーバーを別に立てるのが基本ですが、学習用であるならサービスと同居するスタンドアローン構成の方が気軽ですね。
簡単に自分の設定を書いておきます。
スタンドアローンなサーバーを立ち上げるための設定ファイル
require ::File.expand_path('../config/environment', __FILE__)
Rails.application.eager_load!
run Rails.application
ブラウザからのルームへの接続命令
(function () {
this.App || (this.App = {});
App.cable = Cable.createConsumer("/cable");
}).call(this);
ブラウザからのルームへの接続要求を処理するrouts
mount ActionCable.server => '/cable'
これで、ActionCable機能を利用するサービスのアプリケーションサーバーを立ち上げると、同サーバーを使ってActionCableのcableルームへ接続が確立されるようになりました。
簡単!
終わりに
如何でしょうか。
今思えば初学者ゆえに詰まっただけで、基本的な知識があれば自前でどうにかできる物ばかりな気がしますが...
私と同様の初学者のために参考になれば幸いです。