Turbo入門|Turbo Streamsでリアルタイム更新を実装する方法|Rails × Hotwire

Turbo Streamsを使うと、ページの一部分をリアルタイムに更新したり、ユーザーの操作に応じてDOMを部分的に変更したりできます。
RailsアプリケーションでTurbo Streamsを使ったリアルタイム更新の方法を詳しく解説します。

目次

Turbo Streamsとは?

Turbo Streamsは、HTMLの断片を<turbo-stream>要素でラップしてブラウザに送信し、ページの一部分を動的に更新する仕組みです。
これにより、ページ全体をリロードせずに、特定の要素を追加・削除・置換することが可能になります。

Turbo Streamsは、HTTPレスポンスとして同期的に送信することも、WebSocketやServer-Sent Events(SSE)を使って非同期的に送信することもできます。

Turbo Streamsの基本構造とアクション

Turbo Streamsのメッセージは、以下のようなHTMLの断片です。

<turbo-stream action="append" target="messages">
  <template>
    <div id="message_1">新しいメッセージが追加されます。</div>
  </template>
</turbo-stream>

<turbo-stream>要素は、以下の属性を持ちます。

  • action: DOMに対して行う操作(append, prepend, replace, update, remove, before, after, morph, refresh)
  • target: 操作対象の要素のDOM ID
  • targets: CSSセレクタを使って複数の要素を対象にする場合に使用

Turbo Streamsの主なアクション一覧

Turbo Streamsには以下の9つのアクションがあります。

アクション説明
append対象要素の末尾に追加
prepend対象要素の先頭に追加
replace対象要素を完全に置換
update対象要素の中身を置換(要素自体は残る)
remove対象要素を削除
before対象要素の直前に挿入
after対象要素の直後に挿入
morph対象要素をmorphdomで差分更新
refreshTurbo Frameを再読み込み

RailsでのTurbo Streamsの使い方(HTTPレスポンス)

Railsでは、コントローラーでTurbo Streamsを簡単に返せます。

# messages_controller.rb
def destroy
  @message = Message.find(params[:id])
  @message.destroy

  respond_to do |format|
    format.turbo_stream { render turbo_stream: turbo_stream.remove(@message) }
    format.html { redirect_to messages_url }
  end
end

フォーム送信時にTurbo Streamsを返す場合も同様です。

def create
  @message = Message.create!(message_params)

  respond_to do |format|
    format.turbo_stream do
      render turbo_stream: turbo_stream.append(:messages, partial: "messages/message", locals: { message: @message })
    end
    format.html { redirect_to messages_url }
  end
end

サーバーサイドテンプレートの再利用

Turbo Streamsの最大の利点は、既存のサーバーサイドテンプレートをそのまま再利用できることです。

<!-- app/views/messages/_message.html.erb -->
<div id="<%= dom_id message %>">
  <%= message.content %>
</div>

このテンプレートは、初回ページロード時にも、後から追加されるメッセージにも共通して使えます。

WebSocketやSSEを使ったリアルタイム更新

Turbo StreamsはWebSocketやSSEを使ってリアルタイムに更新を送信できます。

<!-- WebSocketを使った例 -->
<turbo-stream-source src="ws://example.com/cable"></turbo-stream-source>

<!-- SSEを使った例 -->
<turbo-stream-source src="/stream/messages"></turbo-stream-source>

RailsではActionCableを使って簡単に実装できます。

# message.rb (モデル側でブロードキャスト)
class Message < ApplicationRecord
  after_create_commit { broadcast_append_to "messages" }
end

複数要素への一括操作(targets属性)

複数の要素を一括で操作する場合、targets属性を使います。

<turbo-stream action="remove" targets=".old_messages"></turbo-stream>

カスタムアクションの追加

デフォルトの9つのアクション以外に独自のアクションを追加できます。

// JavaScriptでカスタムアクションを追加
import { StreamActions } from "@hotwired/turbo"

StreamActions.alert = function() {
  alert(this.getAttribute("message"))
}
<turbo-stream action="alert" message="Hello, Turbo!"></turbo-stream>

JavaScriptの実行について(Stimulusとの連携)

Turbo Streamsは意図的にJavaScriptの直接実行を制限しています。
追加の動作を実行したい場合は、Stimulusコントローラーを使って実装します。

プログレッシブエンハンスメントの推奨

Turbo Streamsを使う前に、まずは通常のHTTPリクエストで動作するように設計しましょう。
その後、Turbo Streamsを追加してUXを向上させることで、堅牢で柔軟なアプリケーションになります。

まとめ

Turbo Streamsを使うことで、Railsアプリケーションにリアルタイム更新や部分的なDOM操作を簡単に導入できます。
既存のサーバーサイドテンプレートを再利用し、シンプルで保守性の高いコードを実現しましょう。

未経験からエンジニアへ転職!おすすめの転職サービスはこちら

「未経験だけどエンジニアになりたい…」「IT業界に興味があるけど、どこから始めるべきかわからない…」
そんな方におすすめなのが、プログラミングスクールを活用した転職活動です。
実績豊富なスクールを利用すれば、未経験からでもエンジニアとしての転職がぐっと近づきます!

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次