Rails 7 で標準的に利用可能になった turbo-rails は、Hotwire(Hotwired)の一部として提供される Turbo 機能を Rails 上で簡単に使えるようにする仕組みです。従来の Turbolinks を大幅に進化させ、ページ全体をリロードせずに一部のDOMだけを更新する “局所的な動き” を実現できます。
Hotwireとは?
Hotwire は大きく次の3つのライブラリから構成されています。
-
Turbo: SPA 的な体験を実現するためのフレームワーク。
- ページ遷移を高速化する Turbo Drive (旧Turbolinks の進化版)
-
<turbo-frame>
を利用して部分的なページの書き換えを行う Turbo Frames - リアルタイムに部分更新を行う Turbo Streams
- Stimulus: フロントエンドで最小限のJavaScriptを扱うためのライブラリ
- Strada (将来予定): モバイルアプリとの連携周りを最適化する技術(まだベータ的要素がある)
Rails 7 ではデフォルトでこの Turbo が組み込まれ、コントローラ側のレスポンスと組み合わせてフロントエンドを大きく書き換えずに部分更新が行えます。
turbo-rails が提供する主な機能
-
Turbo Frames: 特定の箇所を
<turbo-frame>
タグで囲むことで、サーバーからのレスポンスをそのフレーム部分だけで再描画できるようにする。 -
Turbo Streams: WebSocket (ActionCable) または通常のHTTPリクエストを介してリアルタイムもしくは同期タイミングで部分更新を行う機能。
turbo_stream.erb
形式のビューやrespond_to :turbo_stream
といった書き方が可能。
Turbo Framesで一部分を非同期更新
<!-- app/views/posts/index.html.erb の一例 -->
<h1>Posts</h1>
<!-- この部分をフレーム化する -->
<turbo-frame id="posts_list">
<%= render @posts %>
</turbo-frame>
<!-- 新規投稿ボタンなど -->
<%= link_to "New Post", new_post_path, data: { turbo_frame: "posts_list" } %>
-
id="posts_list"
を持つ<turbo-frame>
タグで一覧部分を囲んでいます。 -
link_to
にオプションでdata: { turbo_frame: "posts_list" }
を付けることで、このリンクの遷移先のレスポンスをposts_list
フレームのみ書き換えるように指定しています。
class PostsController < ApplicationController
def new
@post = Post.new
end
def create
@post = Post.new(post_params)
if @post.save
# 保存後に一覧を再表示したい場合など
redirect_to posts_path
else
render :new, status: :unprocessable_entity
end
end
private
def post_params
params.require(:post).permit(:title, :body)
end
end
これだけでも、上記リンクをクリックした際に <turbo-frame>
の部分だけが再描画されます。
メモ: Turbo Frames はリンク先・フォーム送信先のレスポンスに
<turbo-frame>
タグが含まれていれば差し替えを行う仕組みです。