rails5の機能 action cableを使ってチャット機能を実装してみた


#初めまして
初めまして。初投稿でございますが、よろしくお願いします。早速ですが、今回はrails5の 

機能であるaction cableを使ってチャット機能を作る機会があったので、アウトプットしてみようと 

思います。なおプログラミングという分野を初めて５ヶ月の私に少しでもフィードバックが頂けると

幸いです。

初めての投稿で使い方がわからないand慣れない僕の記事。暖かく見守ってやってくださいw

今回、一度コーディングをしてその後に一つずつ順番に解説するスタイルを取っています。一度、

皆さんにも、動くものを作ってもらった後に、なぜこのように動くのかという部分をみてもらいたい

と思います。

https://qiita.com/port-development/items/120b2bee0cef505a4005

今回上記のURLを参考にしつつ、DBへ保存する処理は自分で実装しました。僕が、Qiitaでの

初めて故にわかりづらい場合はこちらの記事を参考にして頂いた上でDBの保存する処理だけでも見ていた

だければと思います。

#action cableとは

railsアプリケーション上でwebsocket通信による、双方向通信を簡単に実現するための

新しい機能。ちなみにwebsocketとは、サーバーを介してwebブラウザ間で、双方向通信を行う機能。

以前は、rails上でwebsocketを実装するには、複雑な処理を書く必要が

あったそうですが、自分はrails5世代ですのでそんな歴史は知らず・・w

ではどんな機能があるのかを見ていく。


#主な機能

・コネクション
websocket通信をサーバーとクライアント側で接続する機能。繋げるだけ。

・チャンネル(channel)
websocket通信で接続するサーバー側の通信。つまりサーバー側の実装。

・クライアント
websocket通信を使う上で必要なクライアント側の仕組み。ボタンを押すとサーバー側に情報を

POST送信するなど。

・ジェネレイター
rails g コマンドを使った上記のチャネル、クライアント側のファイルの自動生成。

#実装スタート

```mkdir chat(ディレクトリ名)　(ディレクトリの作成)```

```cd chat(ディレクトリ名)　（ディレクトリへ移動）```

```rails new railsアプリケーション名 （railsアプリケーションの作成）
```

個人的にcoffeescriptがあまり好きではないので、こちらの機能を削除するのと、Jqueryを
GemFileに追加します。

```gem 'jquery-rails'
gem 'coffee-rails' ~> # 削除```

追加と削除を行ったら  

```bundle install```

一度反映させましょう。
では、ここでチャットのviewとcontrollerを書いていく。

```rails g controller top```

次にconfig/routes.rbにルーティングを設定します。

```get "/" => "top#show"```

ルーティング後にモデルを作成していきます。

```rails g model Text text:text```

テキストテーブルにテキストカラムでデータ型をテキストで設定しています。（わかりづらくてすいません）

<img width="613" alt="スクリーンショット 2018-05-15 11.24.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/238185/f8771416-c673-6354-bc26-1b9653084c8b.png">

このようにコーディングしてきます。ここでは、後に、javascriptのイベント処理で指定するための
idを指定しているんだなと思ってれば大丈夫だと思います。
form_tagあたりについては、下記でcontrollerの処理について述べていますが結局何をしているのかと言いますと、入力フォームで送信したデータをDBに保存する処理をform_tagで実現しました。

その後、app/controllers/top_controller.rbに

<img width="632" alt="スクリーンショット 2018-05-15 11.33.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/238185/9a245d0d-312b-17f6-0729-6175dd6afd56.png">

ここでは、テキストテーブルのデータを全て受け取るshowアクションを定義して、その後、
createアクションで、show.html.erbファイルのinputタグから送信されたデータをparamsで受け取り
データベースに保存する処理を書いています。

ここまでは普段書いているrailsなのですが、ここから変わってきます。

```rails g channel chat post ```

このコマンドを実行してchannelを作ります。一番初めに書いた通り、channelはサーバー側の実装に
なります。上記のコマンドを実行すると下記のようなファイルができます。

app/channels/chat_channel.rb
<img width="576" alt="スクリーンショット 2018-05-15 11.58.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/238185/7564beda-df92-8340-456f-215710f6e88b.png">

chat_channels.rbでは今回は機能がシンプルなため遠回りしている印象を受けますが、実際はここでDBと接続したり外部アプリと連携したりできます。

app/assets/javascripts/channels/chat.js
<img width="758" alt="スクリーンショット 2018-05-15 12.00.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/238185/b51dbda3-7ff6-005f-5fbd-80af321205e1.png">


そしてこちらのファイルでは、第一引数に今回設定したチャンネル名、そして第二引数には、
サーバー側での処理が記載されています。receivedに注目してください。こちらのreceivedでは
クライアント側から受け取ったデータ(今回の場合、入力フォームから受け取ったデータ)をどの要素に
返すかを指定しています。ここで、先ほど記載したshow.html.erbファイルを見てもらいたいのですが

```<ul id = "chat-index"></ul>```

この部分にサーバー側で受け取ったデータをappendすることを指定しています。
その後、第三引数に下記のイベントの処理を指定しています。
```$(document).on('keypress','[data-behavior~=chat_post]',function(event){```
```if (event.keycode===13){var chatForm = $("#chat-form)};```
```App.chat.post(chatFrom.val());
}}));```

data-behaviorという部分で指定したchat_postはデータを送信する前のクライアント側での処理をどの
要素で行うかを指定しています。そしてその次のfunctionでどういった処理をするのかを指定しています。

ここまででこのようなchatができるかと思われます。


<img width="1315" alt="スクリーンショット 2018-05-16 0.02.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/238185/e704db69-8e86-b863-3807-1d5cc0872bee.png">

この入力フォームに文字列を入れると。。
<img width="958" alt="スクリーンショット 2018-05-16 0.23.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/238185/dfe4d619-eb0f-1686-f309-e257a6802946.png">


このように表示されます。

今回は、チャットの機能実装のためのアウトプットという形で投稿しました。
もし見てくださった方でもっとこうした方がいいなど（記事の書き方、コーディング、デバック）アドバイスがありましたら是非コメントくださると嬉しいです。