今回実装した処理の流れ
フォーム送ると、①非同期のジョブ、②モーダルの表示、③ジョブ結果を描画するテーブルの表示、の3つの動作を同時に行う機能を実装しました。
この記事ではそのturboのでのモーダル表示部分のみを記録しています。
実装したもの
モーダル部分
index.html.erb
<div id='modal-container'></div>
これだけ。ここをturbo_streamによってパーシャルに書き出したものと置き換えることでモーダル画面を描画させる。
同じページのボタン部分
data: { turbo_stream: true }をつけるとコントローラーでturbo_streamのリクエストとして受け取ることが出来ます。
index.html.erb
<%= form_with url: hoge_path(@hoge), scope: :huga, data: { turbo: true } do |f| %>
切り出したパーシャル。bootstrapのモーダルを使っています。
モーダル表示と同時実行で行われる別の処理の終了をもってモーダルを閉じるためにこのような実装をしています。
_modal.html.erb
<div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="modalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">モーダルのタイトル</h5>
</div>
<div class="modal-body">
中身
</div>
</div>
</div>
</div>
<script>
$('#modal').modal('show');
const checkHogeJob =() => {モーダルが表示されている間に実行する別の処理。処理完了後にmodalを再度非表示にする}
</script>
コントローラー部分
controller.rb
def create #ジョブの実行、モーダルの表示、ジョブを保持するテーブルを表示する動作を行う
hoge_log = @hoge.logs.create!
HogeJob.perform_later(hoge_log, @hoge.id)
# respond_toで処理を分ける
respond_to do |format|
format.turbo_stream do
render turbo_stream:
# update:対象のidを持つ要素の中身を書き換える
turbo_stream.update('modal-container', partial: 'admin/hoge/modal', # アドミン配下のときはパスを書かないといけない
locals: { hoge_log_id: hoge_log.id }) +
# ジョブの結果を保持するためのテーブルも同時に表示させた
turbo_stream.update('hoge_logs_table', partial: 'admin/hoge/hoge_logs_table',
locals: { hoge_logs: @hoge_logs })
end
end
end
参考にした記事