そもそもTurboって?
TurboはJSのバンドラー(ex: webpack,esbuildなど)を使わなくても非同期で画面が変わるような処理をしたいときに便利なRails標準機能のこと。HotwireはTurbo, Stimulus, Stradaの3つの相性のことで、詳しく知りたい方はわかりやすい記事もあるのでぜひ。
stimulus-rails gemを読み解く - Qiita
Turbo Framesとは
通常の画面遷移でHTMLが丸ごと置き換わるのに対して、Turbo Framesでは<turbo-frame>…</turbo-frame>
というHTMLタグのようなもので囲った要素が非同期で置き換わります。
何が便利?
ちょっと前まで画面の一部だけ非同期(画面遷移なし)で変更したい、みたいなことがあると思った時は「JSを書きましょう」というのが一般的だったみたいです。そこでJSを書く量を削減できるTurboというRailsが搭載しているJSライブラリがあるみたいです。
Turbo Framesちょこっと試してみる
-
TODOアプリのタスクのupdateアクションを非同期でやってみる
-
実装前の仕様の説明
- 実装前のコード(taskだけパーシャルにしてるよ)
#_task.html.haml .task__name= task.name - if task.description .task__description = safe_join(task.description.split("\n"),tag(:br))
- new/createアクションは作っていてedit/updateはまだ実装していない状態。(画面は下)
- 実装後の仕様
- タスクの名前の右側に編集ボタンを作る
- 編集ボタンをクリックすると
- タスクの名前の部分がフォームに
- 編集ボタンが更新ボタンに
- 更新ボタンをクリックすると
- フォームが元に戻る
- ボタンが元に戻る
- 編集ボタンを追加する
#_task.html.haml
.task__name.d-flex.justify-content-between.mb-1
= task.name
= button_to '編集する', edit_project_task_path(@project), class: 'btn btn-sm btn-outline-primary'
- controllerとroutesを修正してedit/updateアクションを作成
#tasks_controller.rb
def edit
end
def update
if @task.update(task_params)
redirect_to project_path(@project)
else
# renderするときにstatusが必要なので注意
render :edit, status: :unprocessable_entity
end
end
#routes.rb
Rails.application.routes.draw do
resources :projects, only: %i[show new create edit update destroy] do
resources :tasks, only: %i[create edit update]
end
.
.
.
- 差し替えるフォームを作成する
#edit.html.haml
= render 'form'
#_form.html.haml
.task__form
= simple_form_for [@project, task] do |f|
.row
.col-11
= f.input :name, label: false
.col-1
.d-flex.justify-content-end
= f.button :submit, '更新する', class: 'btn btn-sm btn-primary'
- パーシャルを呼び出している箇所をturbo-frame-tagで囲む
#_task.html.haml
= turbo_frame_tag task do
.task__name.d-flex.justify-content-between.mb-1
= task.name
= link_to '編集する', edit_project_task_path(@project), class: 'btn btn-sm btn-outline-primary'
- if task.description
.task__description
= safe_join(task.description.split("\n"),tag(:br))
- 以上で完成です。railsでの実装は
turbo_frame_tag
で差し替えるviewを囲むだけなので非常に簡単ですね! - 完成後の動き
実装中に忘れがちなこと
- TurboFramesは差し替えるviewsをアクション名から探しにいってるので、パーシャルだけ差し替える場合もアクションがレンダリングするviewsを用意する必要があります。