「@step_options が期待する動作をしない件の改善」の2つ目です。
前章は、
Stimulus で、HTML の状態が変わったことをコントローラに伝えて受け取る処理でした。
本章は、受け取ったコントローラが、 画面書き換えに必要な HTML を生成する部分を説明します。
参考リポジトリ: https://github.com/Bonv-dev/book_mgmt/commit/a7e8840 の
\app\views\books\_select_place.html.erb
\app\controllers\books_controller.rb
\app\views\books\select_place.turbo_stream.erb
Turbo Stream は、
View (HTML) の一部だけを更新する仕組みの一つです。
コントローラのアクションでは、
一般に画面(HTML)のページ全体を更新します。
Rails8 のデフォルトでは
通常時でも Turbo Drive で HTML の <body> 部分のみを書き換えるのですが、
その場合は <body> 部分を「全体」と考えて頂ければ。
が、今回は Floor、Cabinet、Step 部分だけを書き換えたい。
その他のデータにまで気を配るのは面倒ですし、
全体を書き換えると画面更新に時間も掛かります。
Turbo Stream を使うことで、指定 ID 範囲のみを書き換えることが可能になります。
通常時に使用する html.erb ファイル上、
Turbo Stream 発動時に書き換える範囲に ID を記載しておきます。
今回なら、
\app\views\books\_select_place.html.erb の
<span id="select_place"> です。
ID の名前文字列は何でも良くて、一意に識別できればOKです。
_select_place.html.erb は、
book 編集画面のファイル \app\views\books\_form.html.erb の中で、
<%= render partial: "select_place" %>
として呼ばれます。
render partial は、指定ファイルの内容をこの場所に貼り付けます。
ファイル名は、先頭にアンダーバー、末尾に (formats).erb を付けたもの。
呼び出し側 _form.html.erb のフォーマットが html なので、
"select_place" なら ```_select_place.html.erb``` になります。
前章の JavaScript が、
\app\controllers\books_controller.rb のアクション select_place を呼んだとします。
メソッドの中では普段と変わらない処理を行って、
画面書き換えに必要な選択肢のデータを揃えたりします。
最後に、
respond_to do |format|
format.turbo_stream
end
部分ですが、
呼び出し時のパラメータで Accept: "text/vnd.turbo-stream.html" を指定しているので、
コントローラは、Turbo Stream での処理依頼だと認識しています。
結果、format.turbo_stream が選択されます。
普段は、\app\views\(コントローラ)\アクション名.html.erb が呼ばれるのですが、
今回は、\app\views\(コントローラ)\アクション名.turbo_stream.erb が呼ばれます。
今回なら \app\views\books\select_place.turbo_stream.erb です。
ちなみに、
respond_to ~ end 部分のコードが無くても、
Turbo Stream 時には .turbo_stream.erb が呼ばれます。
今回の select_place は Turbo Stream でしか使わないので、
つまり、
respond_to ~ end 部分は無くてもいいのですが、
明示しておくほうがコードを読む人間に優しいだろうと思います。
このファイルは特別で、
通常の画面の書き換え内容に加えて、
Turbo Stream で処理すべき指示も含んでいます。
単にファイルの内容を表示するわけではありません。
\app\views\books\select_place.turbo_stream.erb なら以下の通り。
<turbo-stream action="replace" target="select_place">
<template>
<%= render partial: "select_place", formats: :html %>
</template>
</turbo-stream>
turbo-stream タグで、以下の設定を行います。
ちなみに、
select_place.turbo_stream.erb のフォーマットは Turbo Stream ですが、
呼び出す _select_place.html.erb は html なので、
render に "formats: :html" を追加してフォーマットを明示します。
前章と本章で、画面の部分書き換えの説明は終わりました。
最後に、全体の流れを再掲します。