Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Hotwire を使って管理画面を簡単にプチSPA化する - Kaigi on Rails 2023
Search
Takaharu Yamamoto
October 29, 2023
Programming
2
1.6k
Hotwire を使って管理画面を簡単にプチSPA化する - Kaigi on Rails 2023
https://kaigionrails.org/2023/talks/yamataka/
Takaharu Yamamoto
October 29, 2023
Tweet
Share
Other Decks in Programming
See All in Programming
AIによる開発の民主化を支える コンテキスト管理のこれまでとこれから
mulyu
3
510
生成AIを使ったコードレビューで定性的に品質カバー
chiilog
1
280
CSC307 Lecture 03
javiergs
PRO
1
490
Python’s True Superpower
hynek
0
110
QAフローを最適化し、品質水準を満たしながらリリースまでの期間を最短化する #RSGT2026
shibayu36
2
4.4k
疑似コードによるプロンプト記述、どのくらい正確に実行される?
kokuyouwind
0
390
atmaCup #23でAIコーディングを活用した話
ml_bear
1
160
15年続くIoTサービスのSREエンジニアが挑む分散トレーシング導入
melonps
2
230
AIによるイベントストーミング図からのコード生成 / AI-powered code generation from Event Storming diagrams
nrslib
2
1.9k
今から始めるClaude Code超入門
448jp
8
9.1k
MUSUBIXとは
nahisaho
0
140
それ、本当に安全? ファイルアップロードで見落としがちなセキュリティリスクと対策
penpeen
7
4k
Featured
See All Featured
HDC tutorial
michielstock
1
400
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.3k
ラッコキーワード サービス紹介資料
rakko
1
2.3M
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
57
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
170
Heart Work Chapter 1 - Part 1
lfama
PRO
5
35k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
240
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
0
150
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
196
71k
Building Flexible Design Systems
yeseniaperezcruz
330
40k
New Earth Scene 8
popppiees
1
1.5k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.8k
Transcript
Hotwire を使って 管理画⾯を簡単にプチSPA化する Takaharu Yamamoto Kaigi on Rails 2023
⾃⼰紹介 • ⼭本孝春 • GitHub: yamataka22 • 個⼈事業主 • 中⼩規模システムの受託開発をしてます
• Railsで⼀気通貫した開発が好き
Hotwire 使ってますか?
Hotwire 使ってますか? 情報が少ない 実績が少ない とりあえず無効化
Hotwire 使ってますか? 情報が少ない 実績が少ない とりあえず無効化 Turbolinksの⼆の舞に...?!
本⽇のテーマ Hotwireを使って管理画⾯をモーダル化する →この説明を通じて、Hotwireの敷居を下げたい
• 話すこと ◦ HotwireでModalを扱う⽅法を、コードを例⽰しながら実践 レベルで説明します • 話さないこと ◦ 時間の都合上、Hotwireの⼊⾨的な内容(TurboFrameとは 何か?など)は割愛します
今⽇の内容
管理画⾯にモーダルを 使うメリットは? そもそも
よくある画⾯遷移 ⼀覧で検索をして、⾏を選択
よくある画⾯遷移 詳細画⾯に遷移する
よくある画⾯遷移 そこから⼀覧に戻ると indexのPath
よくある画⾯遷移 検索状態がリセットされてしまう
よくある対策 • ブラウザの別タブで表⽰ ◦ assetsを含めた画⾯全体をリロードするので重い ◦ 気づいたらブラウザがタブだらけ • 戻るボタンに検索条件のパラメータを保持 ◦
戻るだけなのに再度検索が⾛る ◦ スクロール位置などは保持されない
⼀覧からの遷移をモーダルで開けば
⼀覧の状態を維持できる
モーダル表⽰のメリット • 画⾯の状態を維持しながら操作を進められる • モーダル内だけ描画するので、挙動が軽い • ユーザーはその画⾯に留まれる安⼼感がある
ただし管理画⾯なので • 開発にそこまでコストをかけたくない • サーバーサイド側のエンジニアだけで UIも含めて実装することが多い
ただし管理画⾯なので • 開発にそこまでコストをかけたくない • サーバーサイド側のエンジニアだけで UIも含めて実装することが多い モーダルのために作り込むことは避けたい
そこで Hotwire
Hotwireなら • ほとんどJavaScriptを書くことなく • ⼀般的な画⾯遷移版に少し⼿を⼊れるだけで • 簡単にモーダル化できる
コードの説明の前に • モーダルの描画にはBootstrapを利⽤します ◦ Bootstrap以外でも、JavaScriptを使ってモーダル表⽰の制御ができれ ば、他のツールでも代替可能です • 時間の都合上、細かな部分は説明を省略します ◦ 本⽇説明するコードはGitHubで公開してます
github.com/yamataka22/kaigionrails2023-admin-modal
やること 1. TurboFrame + Stimulus でモーダルを開く 2. TurboStream で登録後の描画を切り替える 3.
ブラウザのURLを追随させる
やること 1. TurboFrame + Stimulus でモーダルを開く 2. TurboStream で登録後の描画を切り替える 3.
ブラウザのURLを追随させる
モーダル表⽰のポイント • TurboFrameを使って、モーダル部分のHTMLの破⽚を⽣ 成する • その破⽚がブラウザに読み込まれたタイミングで、 Stimulusのインスタンスを⽣成し、connect()を経由して モーダルを開く
app/views/application/_remote_modal.html.erb Modal表⽰のerb (TurboFrame)
app/views/application/_remote_modal.html.erb 中⾝はBootstrapの⼀般的な Modal Component turbo_frame_tag で囲む Modal表⽰のerb (TurboFrame)
app/views/application/_remote_modal.html.erb ポイントはここ! 破⽚の中から、Stimulusの controllerを指定する この破⽚がブラウザに組み込まれたタイミングで 該当Stimulusのインスタンスが⽣成される →TurboFrameとStimulusを連携して、動きをつけられる Modal表⽰のerb (TurboFrame)
app/javascript/controllers/remote_modal_controller.js Modal表⽰のStimulus • `connect()`は、Stimulusのインス タンスが⽣成されたときに⾃動的に 起動するメソッド • TurboFrameで読み込んだHTMLに対 して、Stimulusで動きをつけられる •
`disconnect()`もある
これだけでモーダル表⽰できる 🎉
やること 1. TurboFrame + Stimulus でモーダルを開く 2. TurboStream で登録後の描画を切り替える 3.
ブラウザのURLを追随させる
やること 1. TurboFrame + Stimulus でモーダルを開く 2. TurboStream で登録後の描画を切り替える 3.
ブラウザのURLを追随させる
⼀般的な画⾯遷移による更新処理 編集フォームから更新すると
⼀般的な画⾯遷移による更新処理 エラーがあれば編集画⾯にとどまり
⼀般的な画⾯遷移による更新処理 更新に成功したら詳細画⾯にリダイレクトする
⼀般的な画⾯遷移による更新処理 更新に成功したら詳細画⾯にリダイレクトする モーダルでも同等な動きを実現したい
モーダルでの更新処理 編集フォームから更新すると
モーダルでの更新処理 エラーがあればモーダル上で表示され
モーダルでの更新処理 更新後に詳細画⾯が表⽰される
Controller#update app/controllers/products_controller.rb
Controller#update • 更新に成功しても、redirectしない • update.turbo_stream.erbがレンダリ ング対象 • 本来redirectするパス (product_path) を@turbo_pathにセット
→これは後述にて説明 app/controllers/products_controller.rb
Controller#update invalidの場合は :edit を再度レンダリン グする →これは通常の画⾯遷移時と同様 app/controllers/products_controller.rb
Turbo Stream app/views/products/update.turbo_stream.erb
Turbo Stream remote_modal の部分を @product で `replace` する (モーダルの内容が詳細画⾯に変わる) app/views/products/update.turbo_stream.erb
Turbo Stream app/views/products/update.turbo_stream.erb ⼀覧(index) に表⽰されているレコードの内容も 最新化する
以上で登録後の遷移ができる
やること 1. TurboFrame + Stimulus でモーダルを開く 2. TurboStream で登録後の描画を切り替える 3.
ブラウザのURLを追随させる
やること 1. TurboFrame + Stimulus でモーダルを開く 2. TurboStream で登録後の描画を切り替える 3.
ブラウザのURLを追随させる
管理画⾯の運⽤でよくあるシーン URLを使ってやり取りすることが多々ある 例えばSlackで...
管理画⾯の運⽤でよくあるシーン URLを使ってやり取りすることが多々ある 例えばSlackで... こんな感じで該当ページのURLを使って コミュニケーションしたい
単にModal化しただけでは ブラウザのURLが追随しない →URLを使った運⽤ができない 管理画⾯の実運⽤も考慮して 対処したい
2つの対策を提案 a) モーダル起動の link_to に `turbo_action: :advance` を指定 b) JavaScriptの
History API を使って制御する
2つの対策を提案 a) モーダル起動の link_to に `turbo_action: :advance` を指定 ∙ Railsの仕組みでできるのでシンプル
∙ Modalを閉じたときや、更新後の表⽰切り替え時に追随しない b) JavaScriptの History API を使って制御する ∙ URLのために仕組みを実装する必要 ∙ Modalを閉じたとき、更新後の表⽰切り替えも追随できる
2つの対策を提案 a) モーダル起動の link_to に `turbo_action: :advance` を指定 ∙ Railsの仕組みでできるのでシンプル
∙ Modalを閉じたときや、更新後の表⽰切り替え時に追随しない b) JavaScriptの History API を使って制御する ∙ URLのために仕組みを実装する必要 ∙ Modalを閉じたとき、更新後の表⽰切り替えも追随できる 今回はこちらの内容を説明
以下2つのURLを使う • Modalを表⽰したときのURL ◦ TurboFrameによるGETリクエスト or リダイレクトのURL ◦ Modalを開く際に、HistoryAPIにセットする •
Modalを閉じたときのURL ◦ Modalを開く直前のURLを location.href から取得しておく ◦ Modalのhideイベントをフックして、このURLに戻す
app/controllers/application_controller.rb ApplicationControllerの before_action で、turboでリクエスト されたURLを @turbo_path へセットし ておく Modal起動時のURL GETリクエストでModalを起動する
app/controllers/products_controller.rb 例えば #update に成功すると、通常の画⾯遷移版 では show_path へリダイレクトする。 そのpathを @turbo_path としてセットしておく。
Modal起動時のURL Modalにリダイレクトの動きをさせたい場合
app/views/application/_remote_modal.html.erb @turbo_path をModalに付与しておき、Stimulusを介 してHistoyAPIにセットする 前項で説明した turbo_frame でModal表示をするerb
app/javascript/controllers/remote_modal_controller.js 前述で説明した、Stimulusのconnect()を使って Modalを開くロジック部分 Modalを起動するStimulus
Modalを開く前に、URLの仕組みを ⼊れる app/javascript/controllers/remote_modal_controller.js Modalを起動するStimulus
app/javascript/controllers/remote_modal_controller.js Modalを起動するStimulus 前述の `turboPath` を HistoryAPIにセットするこ とで、Modal起動時にURLを追随させる
現在のパス=Modalを開く直前のパ ス (`location.href`) を、Modal#hide イベントをフックしてセットする app/javascript/controllers/remote_modal_controller.js Modalを起動するStimulus
以上でブラウザ上のURLが追随します
ちなみに、この状態で URLを直接指定したリクエストをすると...
特に何も仕組みを設けなくても表⽰できる
コード補足 a) 登録フォームのModalは、背景クリックでも閉じないように • ⼊⼒途中にうっかりModalが閉じることを防ぐ • 詳細ページなら背景クリックで閉じたほうが便利 b) Flashによるメッセージ表⽰ •
Turboだと少し仕組みを設ける必要 サンプルのGitHubリポジトリで実装しています github.com/yamataka22/kaigionrails2023-admin-modal
まとめ • Hotwireを使って、管理画⾯をModalでプチSPA化するポイントを説明 しました ◦ TurboFrameとStimulus (connect()) を連携させて、HTMLの破⽚に動き をつける ◦
TurboStreamで、Modal上の描画を切り替える(リダイレクトのイメー ジ) • 今回説明した内容は、管理画⾯はもちろん、⼀般的なフロント向け ページでも応⽤可能です
ご清聴ありがとうございました ※ご不明な点などあれば、お気軽にご連絡ください github.com/yamataka22