🛤️
RailsのflashメッセージをTurbo Streamsで
TurboはRailsに関わらず使えるものですが、今回はRailsの機能に依存した話です。
以下は
-
@hotwired/turbo
:7.0.0-beta.8
-
turbo-rails
:0.5.12
を前提としています。
Railsと組み合わせてある程度Turboを使ってみて、HTTPレスポンスとしてTurbo Streamsを使うのは自分が想定していたよりもかなり使いどころがあるなと分かってきました。副作用があるリクエストの場合、レールに乗るならflash
を利用してユーザに結果を伝えることになるのかなと思います。Turbo Streamsの場合に、自分がどのようにflashメッセージを使っているかをまとめてみることにしました。
ポイントとしては以下の2点です。
- Trubo Streams用のlayoutを用意する
- Turbo Streamsでのレスポンスを返す際には
flash.now
を使う
RJSを使っているなら大体同じようなことをしてるかと思います。
Turbo Streams用のlayoutを用意する
以下のようなlayoutを用意しておけば、Turbo Streamsのレスポンスを返す際に #alerts
に app/views/application/_alert.html.erb
のrender結果を追加してくれます。
app/views/layout/application.turbo_stream.erb
<% if flash[:notice] %>
<%= turbo_stream.append("alerts") do %>
<%= render "application/alert", type: :info, message: flash[:notice] %>
<% end %>
<% end %>
<% if flash[:alert] %>
<%= turbo_stream.append("alerts") do %>
<%= render "application/alert", type: :warning, message: flash[:alert] %>
<% end %>
<% end %>
<%= yield %>
アプリケーションに合わせて適宜調整してください。
flash.now
を使う
Turbo Streamsでのレスポンスを返す際には Turbo Streamsでレスポンスを返す場合、リダイレクトをはさまないので flash.now
を使う必要があります。Turbo Streamsを受けれてくれない場合にはリダイレクトしたいので、僕は request.format
に応じて適切なものを使うためのメソッド ApplicationController
に定義してしまっています(concernに切り出した方が良いかも)。
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
# ...
def appropriate_flash
case
when request.format.turbo_stream?
flash.now
else
flash
end
end
# ...
end
単純化したコントローラでの利用例は以下のようになります。
app/controllers/comments_controller.rb
class CommentsController < ApplicationController
def create
comment = Comment.create!(create_params)
appropriate_flash[:notice] = "コメントを投稿しました"
respond_to do |format|
format.turbo_stream # app/views/comments/create.turbo_stream.erb
format.any { redirect_to comments_path }
end
end
# ...
end
以上です。
Discussion