38
40

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

RailsのActionCableでチャット機能を作ってみた

Last updated at Posted at 2018-11-02

#初めまして
初めまして。初投稿でございますが、よろしくお願いします。早速ですが、今回はrails5の
機能であるaction cableを使ってチャット機能を作る機会があったので、アウトプットしてみようと思います。
なおプログラミングという分野を初めて5ヶ月の私に少しでもフィードバックが頂けると
幸いです。
初めての投稿で使い方がわからないand慣れない僕の記事。暖かく見守ってやってくださいw
今回、一度コーディングをしてその後に一つずつ順番に解説するスタイルを取っています。一度、
皆さんにも、動くものを作ってもらった後に、なぜこのように動くのかという部分をみてもらいたいと思います。

今回上記の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

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

views/show.html.erb

<h1>Chat</h1>
<ul id="chat-index">
  <% @text.each do |message| %>
  <li><%= message.text %></li>
  <% end %>
</ul>
<%= form_tag("/create") do %>
  <input id="chat-form" type="text" data-behavior="chat_post" name="message" value="入力">
<% end %>

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

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

class TopController < ApplicationController
  def show
    @text = text.all
  end

  def create
    @texts = Text.new(text.params[:message])
    @texts.save
  end
end

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

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

rails g channel chat post 

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

app/channels/chat_channel.rb

class ChatChannel < ApplicationCable::Channel
  def subscribed
    stream_form 'chat_channel'
  end
  
  def unsubscribed
  end

  def post(data)
    ActionCable.server.broadcast('chat_channel', data)
  end
end

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

app/assets/javascripts/channels/chat.js

App.chat = App.cable.subscriptions.create("ChatChannel", {
  connected: function(){
    //called when the subscription is ready for use on the server
  },
  
  disconnected: function(){
    //called when the subscription has been terminated by the server
  },

  received: function(data){
    return $('#chat-index).append('<li>' + data.message + '</li>');
  }, 
  
  $(document).on('keypress', '[data-behavior~=chat_post]', function(event){
    if(event.keyCode === 13){
      var chatForm = $('#chat-form');
      App.chat.post(chatForm.val());
      return;
    }
  })
);

そしてこちらのファイルでは、第一引数に今回設定したチャンネル名、そして第二引数には、サーバー側での処理が記載されています。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(chatForm.val());
      return;
    }
})

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

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

スクリーンショット 2018-05-16 0.02.10.png

この入力フォームに文字列を入れると。。
スクリーンショット 2018-05-16 0.23.51.png

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

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

 

 

38
40
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
38
40

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?