ActionCableとTurboを使用してRailsでリアルタイムチャットアプリを構築する
Facebookにアクセスして、ページを更新せずに通知を受け取ったことはありますか?この種のリアルタイム機能は、状態管理を介したReactなどのJavaScriptフレームワークを使用するほとんどのアプリケーションで実現されます。これらのアプリケーションのほとんどは、データをリアルタイムで更新するために使用中にページをリロードする必要がないため、シングルページアプリケーションとして機能します。Railsアプリケーションは、通常、ページのリロードが必要であるという意味で、ステートレスでした。アプリケーションの現在の状態。たとえば、劇場で利用可能な映画のリストを表示するRailsアプリを使用していて、映画が管理者によって追加された場合、ページを更新しない限り、新しく追加された映画はダッシュボードに表示されません。
なぜActionCableなのか?
ActionCableはこのギャップを埋め、Railsアプリケーションでリアルタイムの更新とこの動的な機能を利用できるようにします。 WebSocketと呼ばれる通信プロトコルを利用して、パフォーマンスとスケーラブルを維持しながら、アプリケーションに状態を導入します。これにより、ユーザーはページを更新しなくてもダッシュボードで更新されたコンテンツを取得できます。
TurboRailsは、ターボドライブ、ターボフレーム、およびターボストリームで構成されています。ターボフレームでラップされたページの一部からリクエストが送信されると、同じIDを持っている場合、HTML応答によって、出力されたフレームが置き換えられます。一方、ターボストリームでは、これらの部分的なページ更新をWeb上で有効にします。ソケット接続。 ActionCableはこれらの更新をチャネルからブロードキャストし、Turboストリームはこのチャネルのサブスクライバーを作成して更新を配信します。その結果、モデルの変更に応じて非同期更新を直接作成できます。
この記事の目的は、Turboが舞台裏でActionCableと連携して、Rails6アプリでリアルタイムの更新をブロードキャストおよび表示する方法を紹介することです。そのため、どのユーザーでもチャットルームを作成でき、すべてのユーザーがそのルームにメッセージを送信したり、リアルタイムで更新を受信したりできるチャットアプリを構築します。また、ユーザー同士がプライベートにチャットできるようにします。グループチャットの招待は実装しません。 TurboやActionCableではなく、追加のデータベース設計のみが含まれるため、これらはこのブログ投稿の範囲を超えています。ただし、このレッスンの後、さらに先に進むことを選択した場合は、簡単なことになるはずです。
これはどのように見えるべきですか、それとも何を伴うべきですか?
- 既存のすべてのチャットルームとユーザーを一覧表示するインデックスページ。
- このページは、新しいユーザーが登録したとき、または新しい部屋が作成されたときに動的に更新される必要があります。
- 新しいチャットルームを作成するためのフォームがあります。
- チャットルームにいるときにメッセージを作成するためのメッセージチャットボックス。
このアプリでは、ユーザーは一意のユーザー名を使用してのみログインする必要があります。これは、セッションを使用して実現されます。
1。新しいRailsアプリを作成する
rails new chatapp
cd chatapp
2。ユーザーモデルを作成して移行する
rails g model User username
rails db:migrate
次に、すべてのユーザー名を所有者に一意にするため、ユーザー名に一意の検証を追加します。また、ユーザーが自分自身とチャットしたくないため、ユーザーリストの現在のユーザーを除くすべてのユーザーをフェッチするスコープを作成します:)
#app/models/user.rb
class User < ApplicationRecord
validates_uniqueness_of :username
scope :all_except, ->(user) { where.not(id: user) }
end
3。チャットルームモデルを作成する
チャットルームには名前があり、プライベートチャットルーム(2人のユーザー間のプライベートチャット用)またはパブリック(すべてのユーザーが利用可能)にすることができます。これを示すために、is_private
を追加します 部屋のテーブルへの列。
rails g model Room name:string is_private:boolean
このファイルを移行する前に、デフォルト値をis_private
に追加します 特に明記されていない限り、作成されたすべての部屋がデフォルトで公開されるように列を作成します。
class CreateRooms < ActiveRecord::Migration[6.1]
def change
create_table :rooms do |t|
t.string :name
t.boolean :is_private, :default => false
t.timestamps
end
end
end
この手順の後、コマンドrails db:migrate
を使用してファイルを移行します。 。また、nameプロパティの一意性検証と、ルームリストのすべてのパブリックルームをフェッチするスコープを追加する必要があります。
#app/models/room.rb
class Room < ApplicationRecord
validates_uniqueness_of :name
scope :public_rooms, -> { where(is_private: false) }
end
4。スタイリングを追加
このアプリに最小限のスタイルを追加するために、ブートストラップCDNをapplication.html.erbファイルに追加します
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
5。認証を追加
アプリに認証を追加するには、current_user
が必要です 常に可変。記載されているファイルに次のコードをアプリに追加して、認証を有効にしましょう。
#app/controllers/application_controller.rb
helper_method :current_user
def current_user
if session[:user_id]
@current_user = User.find(session[:user_id])
end
end
def log_in(user)
session[:user_id] = user.id
@current_user = user
redirect_to root_path
end
def logged_in?
!current_user.nil?
end
def log_out
session.delete(:user_id)
@current_user = nil
end
#app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def create
user = User.find_by(username: params[:session][:username])
if user
log_in(user)
else
render 'new'
end
end
def destroy
log_out if logged_in?
redirect_to root_path
end
end
#app/views/sessions/new.html.erb
<%= form_for (:session) do |f| %>
<%= f.label :username, 'Enter your username' %>
<%= f.text_field :username, autocomplete: 'off' %>
<%= f.submit 'Sign in' %>
<% end %>
次のルートをroutes.rbファイルに追加します。
#routes.rb
Rails.application.routes.draw do
get '/signin', to: 'sessions#new'
post '/signin', to: 'sessions#create'
delete '/signout', to: 'sessions#destroy'
end
6。コントローラを作成する
rails g controller Rooms index
を使用してRoomsControllerを作成します ユーザーと部屋のリストの変数をインデックスメソッドに追加します。
class RoomsController < ApplicationController
def index
@current_user = current_user
redirect_to '/signin' unless @current_user
@rooms = Room.public_rooms
@users = User.all_except(@current_user)
end
end
7。ルートを設定する
部屋、ユーザー、ルートルートをroutes.rb
に追加します ランディングページがすべての部屋とユーザーを一覧表示するインデックスページになり、選択した任意の部屋に移動できるようにします。
#routes.rb
resources :rooms
resources :users
root 'rooms#index'
Turboの「魔法」の最初の紹介は、新しく追加された部屋または新しくサインアップしたユーザーの場合にダッシュボードでリアルタイムの更新を受信することです。これを実現するために、まず、2つのパーシャルを作成します。_room.html.erb
各部屋と_user.html.erb
を表示します 各ユーザーを表示します。このリストをindex.html.erb
にレンダリングします これはランディングページであるため、RoomsControllerの作成時に作成されたファイル。
# app/views/rooms/_room.html.erb
<div> <%= link_to room.name, room %> </div>
# app/views/users/_user.html.erb
<div> <%= link_to user.username, user %> </div>
これらのファイルをindex.html.erb
にレンダリングします。 ファイルを直接参照するのではなく、コレクションをフェッチする変数をレンダリングします。 RoomsControllerの変数@users
を思い出してください。 および@rooms
すでに定義されています。
#app/views/rooms/index.html.erb
<div class="container">
<h5> Hi <%= @current_user.username %> </h5>
<h4> Users </h4>
<%= render @users %>
<h4> Rooms </h4>
<%= render @rooms %>
</div>
コンソールで、次のコマンドを実行します。
Room.create(name: 'music')
User.create(username: 'Drake')
User.create(username: 'Elon')
rails s
を使用してRailsサーバーの電源を入れます 。サインインするように求められます。上で作成したユーザーのユーザー名を使用してこれを行います。新しく作成した部屋と、サインインしなかったユーザーが下の画像に示すように表示されます。
リアルタイムの更新を実現するには、Turboをインストールする必要があります。
bundle add turbo-rails
rails turbo:install
Redisがインストールされていない場合は、次のコマンドを実行します。
sudo apt install redis-server
#installs redis if you don't have it yet
redis-server
#starts the server
turbo-rails
をインポートします application.js
に import "@hotwired/turbo-rails"
を使用したファイル
次に、モデルに特定の指示を追加し、新しく追加されたインスタンスを特定のチャネルにブロードキャストするようにモデルに依頼します。このブロードキャストは、後で説明するように、ActionCableによって行われます。
#app/models/user.rb
class User < ApplicationRecord
validates_uniqueness_of :username
scope :all_except, ->(user) { where.not(id: user) }
after_create_commit { broadcast_append_to "users" }
end
ここでは、ユーザーの新しいインスタンスが作成されるたびに、ユーザーモデルに「users」というチャネルにブロードキャストするように依頼しています。
#app/models/room.rb
class Room < ApplicationRecord
validates_uniqueness_of :name
scope :public_rooms, -> { where(is_private: false) }
after_create_commit {broadcast_append_to "rooms"}
end
ここでは、部屋の新しいインスタンスが作成されるたびに、部屋モデルに「部屋」と呼ばれるチャネルにブロードキャストするように依頼しています。
コンソールがまだ起動していない場合は起動するか、reload!
を使用します すでに稼働している場合はコマンド。これらのいずれかの新しいインスタンスを作成した後、ActionCableは、追加されたインスタンスをテンプレートとして割り当てられた部分を使用して、ターボストリームとして指定されたチャネルにブロードキャストすることがわかります。新しく追加された部屋の場合、部分的な_room.html.erb
をブロードキャストします。 以下に示すように、新しく追加されたインスタンスに対応する値を使用します。
ただし、問題は、ブロードキャストされたテンプレートがダッシュボードに表示されないことです。これは、ActionCableによってブロードキャストされたものをすべて受信して追加できるように、ブロードキャストのレシーバーをビューに追加する必要があるためです。これを行うには、turbo_stream_from
を追加します。 タグ、ブロードキャストの受信を希望するチャネルを指定します。上の画像に見られるように、ブロードキャストされたストリームにはターゲット属性があり、これはストリームが追加されるコンテナのIDを指定します。これは、ブロードキャストされたテンプレートが、追加する「部屋」のIDを持つコンテナを検索することを意味します。したがって、インデックスファイルに上記のIDを持つdivを含めます。これを実現するには、index.html.erb
に ファイルの場合、<%= render @users %>
を置き換えます と:
<%= turbo_stream_from "users" %>
<div id="users">
<%= render @users %>
</div>
および<%= render @rooms %>
と
<%= turbo_stream_from "rooms" %>
<div id="rooms">
<%= render @rooms %>
</div>
この瞬間、ターボの魔法を体験することができます。ページを更新して、コンソールから新しいユーザーとルームを追加し始め、それらがリアルタイムでページに追加されるのを見ることができます。イッピー!!!
コンソールから新しい部屋を作成するのにうんざりしていませんか?ユーザーが新しい部屋を作成できるフォームを追加しましょう。
#app/views/layouts/_new_room_form.html.erb
<%= form_with(model: @room, remote: true, class: "d-flex" ) do |f| %>
<%= f.text_field :name, class: "form-control", autocomplete: 'off' %>
<%= f.submit data: { disable_with: false } %>
<% end %>
上記のフォームでは、@room
が使用されていますが、コントローラーではまだ定義されていません。したがって、これを定義して、RoomsControllerのインデックスメソッドに追加します。
@room = Room.new
作成ボタンをクリックすると、RoomsControllerのcreateメソッドにルーティングされますが、現在は存在していません。したがって、追加する必要があります。
#app/controllers/rooms_controller.rb
def create
@room = Room.create(name: params["room"]["name"])
end
このフォームを部分的にレンダリングすることで、このフォームをインデックスファイルに追加できます。
<%= render partial: "layouts/new_room_form" %>
また、いくつかのブートストラップクラスを追加して、ページを部屋とユーザーのリスト用の部分とチャット用の部分に分割することもできます。
<div class="row">
<div class="col-md-2">
<h5> Hi <%= @current_user.username %> </h5>
<h4> Users </h4>
<div>
<%= turbo_stream_from "users" %>
<div id="users">
<%= render @users %>
</div>
</div>
<h4> Rooms </h4>
<%= render partial: "layouts/new_room_form" %>
<div>
<%= turbo_stream_from "rooms" %>
<div id="rooms">
<%= render @rooms %>
</div>
</div>
</div>
<div class="col-md-10 bg-dark">
The chat box stays here
</div>
</div>
追加された部屋の画像がリアルタイムで更新されます
これで、新しい部屋を作成すると、これらの部屋が作成され、ページがリアルタイムで更新されていることがわかります。また、送信するたびにフォームがクリアされないことにも気付いたと思います。この問題は、後で刺激を使用して処理します。
グループチャットの場合、個々の部屋にルーティングできる必要がありますが、同じページにとどまります。これを行うには、インデックスページに必要なすべての変数をRoomsController showメソッドに追加し、インデックスページを静止させます。
#app/controllers/rooms_controller.rb
def show
@current_user = current_user
@single_room = Room.find(params[:id])
@rooms = Room.public_rooms
@users = User.all_except(@current_user)
@room = Room.new
render "index"
end
@single_room
という名前の追加の変数 showメソッドに追加されました。これにより、ルーティング先の特定の部屋が得られます。したがって、部屋の名前がクリックされたときに移動した部屋の名前を示す条件ステートメントをインデックスページに追加できます。これは、クラス名col-md-10
でdiv内に追加されます 、以下に示すように。
<div class="col-md-10 bg-dark text-light">
<% if @single_room %>
<h4 class="text-center"> <%= @single_room.name %> </h4>
<% end %>
</div>
複数の部屋への移動を示す画像
次に、もっとジューシーなメッセージ、メッセージングに移ります。チャットセクションの高さを100vhにして、ページ全体に表示し、メッセージ作成用のチャットボックスを含める必要があります。チャットボックスにはメッセージモデルが必要です。メッセージは作成者とそれが意図された部屋なしでは存在できないため、このモデルにはユーザー参照と部屋参照があります。
rails g model Message user:references room:references content:text
rails db:migrate
また、ユーザーモデルと部屋モデルに次の行を追加して、この関連付けを特定する必要があります。
has_many :messages
メッセージ作成用のフォームをページに追加して、スタイルを追加しましょう:
#app/views/layouts/_new_message_form.html.erb
<div class="form-group msg-form">
<%= form_with(model: [@single_room ,@message], remote: true, class: "d-flex" ) do |f| %>
<%= f.text_field :content, id: 'chat-text', class: "form-control msg-content", autocomplete: 'off' %>
<%= f.submit data: { disable_with: false }, class: "btn btn-primary" %>
<% end %>
</div>
#app/assets/stylesheets/rooms.scss
.msg-form {
position: fixed;
bottom: 0;
width: 90%
}
.col-md-10 {
height: 100vh;
overflow: scroll;
}
.msg-content {
width: 80%;
margin-right: 5px;
}
このフォームには@message
が含まれています 変数;したがって、コントローラーで定義する必要があります。これをRoomsControllerのshowメソッドに追加します。
@message = Message.new
routes.rb
で ファイルの場合、部屋のリソース内にメッセージリソースを追加します。これは、メッセージの作成元である部屋のIDであるparamsに添付されます。
resources :rooms do
resources :messages
end
新しいメッセージが作成されるたびに、それが作成された部屋にブロードキャストされるようにします。これを行うには、メッセージをレンダリングする部分的なメッセージが必要です。これが放送されるものなので、turbo_stream
も必要です その特定の部屋のブロードキャストメッセージと、これらのメッセージを追加するためのコンテナとして機能するdivを受信します。このコンテナのIDは、ブロードキャストのターゲットと同じである必要があることを忘れないでください。
これをメッセージモデルに追加します:
#app/models/message.rb
after_create_commit { broadcast_append_to self.room }
このようにして、作成された特定の部屋にブロードキャストします。
また、ストリーム、メッセージコンテナ、メッセージフォームをインデックスファイルに追加します。
#within the @single_room condition in app/views/rooms/index.html.erb
<%= turbo_stream_from @single_room %>
<div id="messages">
</div>
<%= render partial: 'layouts/new_message_form' >
ブロードキャストされるメッセージパーシャルを作成し、その中に、部屋が公共のものである場合にのみ送信者のユーザー名を表示します。
#app/views/messages/_message.html.erb
<div>
<% unless message.room.is_private %>
<h6 class="name"> <%= message.user.username %> </h6>
<% end %>
<%= message.content %>
</div>
コンソールからメッセージを作成すると、割り当てられたテンプレートを使用してその部屋にメッセージがブロードキャストされていることがわかります。
ダッシュボードからのメッセージ作成を有効にするには、createメソッドをMessagesControllerに追加する必要があります。
#app/controllers/messages_controller.rb
class MessagesController < ApplicationController
def create
@current_user = current_user
@message = @current_user.messages.create(content: msg_params[:content], room_id: params[:room_id])
end
private
def msg_params
params.require(:message).permit(:content)
end
end
これが私たちが得るものです:
上のビデオでわかるように、メッセージは追加されていますが、別のチャットルームに移動すると、戻ったときに前のチャットルームのメッセージが失われたように見えます。これは、表示用の部屋に属するメッセージをフェッチしていないためです。これを行うには、RoomsController showメソッドで、部屋に属するすべてのメッセージをフェッチする変数を追加し、インデックスページで、フェッチされたメッセージをレンダリングします。また、メッセージの送信後にメッセージフォームがクリアされないこともわかります。これは、今後の刺激で処理されます。
#in the show method of app/controllers/rooms_controller.rb
@messages = @single_room.messages
#within the div with id of 'messages'
<%= render @messages %>
これで、各部屋の入り口にメッセージが読み込まれます。
現在のユーザーのメッセージを右に、他のユーザーのメッセージを左に揃えて、これをより見やすくする必要があります。これを実現する最も簡単な方法は、条件message.user == current_user
に基づいてクラスを割り当てることです。 、ただし、ローカル変数はストリームで使用できません。したがって、ブロードキャストされたメッセージの場合、current_user
はありません。 。私たちは何ができる?メッセージ送信者IDに基づいてメッセージコンテナにクラスを割り当ててから、current_user
を利用できます。 application.html.erb
にスタイルを追加するためのヘルパーメソッド ファイル。このように、現在のユーザーのIDが2の場合、application.html.erb
のスタイルタグのクラス .msg-2
になります 、これは、メッセージの送信者が現在のユーザーである場合、メッセージの部分的なクラスにも対応します。
#app/views/messages/_message.html.erb
<div class="cont-<%= message.user.id %>">
<div class="message-box msg-<%= message.user.id %> " >
<% unless message.room.is_private %>
<h6 class="name"> <%= message.user.username %> </h6>
<% end %>
<%= message.content %>
</div>
</div>
message-box
を追加します スタイリング:
#app/assets/stylesheets/rooms.scss
.message-box {
width: fit-content;
max-width: 40%;
padding: 5px;
border-radius: 10px;
margin-bottom: 10px;
background-color: #555555 ;
padding: 10px
}
application.html.erb
のヘッドタグ内 ファイル。
#app/views/layouts/application.html.erb
<style>
<%= ".msg-#{current_user&.id}" %> {
background-color: #007bff !important;
padding: 10px;
}
<%= ".cont-#{current_user&.id}" %> {
display: flex;
justify-content: flex-end
}
</style>
!important
を追加します background-color
にタグを付ける 現在のユーザーの背景色を上書きしたいからです。
チャットは次のようになります。
プライベートチャットに必要な作業のほとんどは、グループチャットのセットアップ中に行われました。今やらなければならないことは次のとおりです。
- 特定のユーザーにルーティングするときに、そのような部屋が存在しない場合は、プライベートチャット用の個室を作成します。
- そのような部屋の参加者を作成して、侵入者がコンソールからでもそのような部屋にメッセージを送信できないようにします。
- 新しく作成された個室がルームリストにブロードキャストされないようにします。
- プライベートチャットの場合は、部屋の名前ではなくユーザーの名前を表示します。
特定のユーザーにルーティングする際、現在のユーザーは、そのユーザーとプライベートにチャットしたいことを示しています。したがって、UsersController
、この2つの間にそのような個室が存在するかどうかを確認します。もしそうなら、それは私たちの@single_room
になります 変数;それ以外の場合は、作成します。プライベートチャットルームごとに特別な部屋名を作成し、必要なときに参照できるようにします。また、同じページにとどまるには、showメソッドにインデックスページに必要なすべての変数を含める必要があります。
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
@current_user = current_user
@rooms = Room.public_rooms
@users = User.all_except(@current_user)
@room = Room.new
@message = Message.new
@room_name = get_name(@user, @current_user)
@single_room = Room.where(name: @room_name).first || Room.create_private_room([@user, @current_user], @room_name)
@messages = @single_room.messages
render "rooms/index"
end
private
def get_name(user1, user2)
users = [user1, user2].sort
"private_#{users[0].id}_#{users[1].id}"
end
end
上記のように、create_private_room
を追加する必要があります 個室とその参加者を作成するRoomモデルのメソッド。これにより、Participant
という新しいモデルを作成できます。 、ユーザーとそのユーザーが所属する個室を示します。
rails g model Participant user:references room:references
rails db:migrate
部屋モデルでは、create_private_room
を追加します メソッドを変更し、after_create
を変更します 個室でない場合にのみ、部屋の名前をブロードキャストするように呼び出します。
#app/models/room.rb
has_many :participants, dependent: :destroy
after_create_commit { broadcast_if_public }
def broadcast_if_public
broadcast_append_to "rooms" unless self.is_private
end
def self.create_private_room(users, room_name)
single_room = Room.create(name: room_name, is_private: true)
users.each do |user|
Participant.create(user_id: user.id, room_id: single_room.id )
end
single_room
end
他のユーザーが参加者でないときに個室にメッセージを送信できないようにするために、before_create
を追加します メッセージモデルを確認してください。したがって、個室の場合、そのようなメッセージが作成される前に、メッセージの送信者が実際にそのプライベート会話の参加者であることが確認されます。ダッシュボードから、参加者でない場合は、ユーザー名をクリックするだけで両方のユーザー用に部屋が作成されるため、個室にメッセージを送信することはできません。このチェックは、参加者以外のユーザーがコンソールからメッセージを作成できるため、セキュリティを強化するためのものです。
#app/models/message.rb
before_create :confirm_participant
def confirm_participant
if self.room.is_private
is_participant = Participant.where(user_id: self.user.id, room_id: self.room.id).first
throw :abort unless is_participant
end
end
プライベートチャット中に部屋の名前の代わりにユーザーのユーザー名を表示するために、インデックスページに@user
変数が存在する場合、ユーザーのユーザー名が表示されます。この変数は、UsersControllershowメソッドにのみ存在することに注意してください。これにより、部屋名を示すh4タグが次のように変更されます:
<h4 class="text-center"> <%= @user&.username || @single_room.name %> </h4>
これで、ユーザーに移動すると、部屋の名前ではなくユーザーのユーザー名が表示され、メッセージを送受信できます。サインアウトリンクをホームページに追加することを忘れないでください。
<%= link_to 'Sign Out', signout_path, :method => :delete %>
以下に示すように、プライベートチャットの場合、送信者のユーザー名は表示されません。私たちは自分のメッセージをその位置によって識別することができます。
フルページの再レンダリングは行われず、新しいモデルインスタンスの作成時にフォームがクリアされないため、スティミュラスを使用してフォームをクリアします。
bundle add stimulus-rails
rails stimulus:install
これにより、次の画像に示すように、次のファイルが追加されます。
reset_form_controller.js
を作成します ファイルを作成してフォームをリセットし、次の関数を追加します。
//app/javascript/controllers/reset_form_controller.js
import { Controller } from "stimulus"
export default class extends Controller {
reset() {
this.element.reset()
}
}
次に、フォームにデータ属性を追加して、コントローラーとアクションを示します。
data: { controller: "reset-form", action: "turbo:submit-end->reset-form#reset" }
たとえば、form_with
メッセージフォームのタグが次のように変更されます:
<%= form_with(model: [@single_room ,@message], remote: true, class: "d-flex",
data: { controller: "reset-form", action: "turbo:submit-end->reset-form#reset" }) do |f| %>
最後に、必要なのはこれだけです。新しいメッセージまたは部屋を作成すると、フォームがクリアされます。また、刺激アクション"ajax:success->reset-form#reset"
にも注意する必要があります。 ajax:success
のときにフォームをクリアすることもできます イベントが発生します。
このアプリでは、Turbo Streamsの追加アクションに焦点を当てていますが、TurboStreamsに必要なのはこれだけではありません。実際、Turbo Streamsは、追加、追加、置換、更新、削除の5つのアクションで構成されています。チャットメッセージの削除と更新をリアルタイムで実装するには、これらのアクションが役立ち、Turboフレームとその動作についての知識が必要になる場合があります。また、特定のWebSocket更新に依存するアプリケーションの場合は注意が必要です。機能、接続不良、またはサーバーの問題がある場合、WebSocketが切断される可能性があります。したがって、非常に重要な場合にのみ、アプリでTurboStreamsを使用することをお勧めします。
-
React on Rails:シンプルなアプリの構築
アプリケーションのフロントエンド側全体を構築する企業は、多くの場合、バックエンドを構築するためにRailsなどの同じフレームワークを選択します。長年にわたり、これは最良かつ最も信頼できるオプションでした。 今日、絶えず進化するフロントエンドユニバースにある多数のライブラリとフレームワークにより、開発者はバックエンドとフロントエンドの両方に異なるプラットフォームを選択し、それらを簡単に統合できます。 Reactはフロントエンドのパンゲアの巨人になりました。 Ruby on Railsを使用している場合は、デフォルトのRailsページをReactコード(またはその他のフロントフレームワーク)に
-
Rails5でのAngularの使用
あなたは前にその話を聞いたことがあります。分散型で完全に機能するバックエンドAPIと、通常のツールセットで作成されたフロントエンドで実行されているアプリケーションがすでにあります。 次に、Angularに移動します。または、AngularをRailsプロジェクトと統合する方法を探しているだけかもしれません。これは、この方法を好むためです。私たちはあなたを責めません。 このようなアプローチを使用すると、両方の世界を活用して、たとえばRailsとAngularのどちらの機能を使用してフォーマットするかを決定できます。 構築するもの 心配する必要はありません。このチュートリアルは、この目的のた