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
モデル駆動設計をやってみようワークショップ開催報告(Modeling Forum2025) / model driven design workshop report
haru860
0
290
gunshi
kazupon
1
120
著者と進める!『AIと個人開発したくなったらまずCursorで要件定義だ!』
yasunacoffee
0
160
Implementation Patterns
denyspoltorak
0
130
AI 駆動開発ライフサイクル(AI-DLC):ソフトウェアエンジニアリングの再構築 / AI-DLC Introduction
kanamasa
11
4.3k
AI前提で考えるiOSアプリのモダナイズ設計
yuukiw00w
0
190
Java 25, Nuevas características
czelabueno
0
120
ゆくKotlin くるRust
exoego
1
160
Pythonではじめるオープンデータ分析〜書籍の紹介と書籍で紹介しきれなかった事例の紹介〜
welliving
3
630
ZJIT: The Ruby 4 JIT Compiler / Ruby Release 30th Anniversary Party
k0kubun
1
290
Spinner 軸ズレ現象を調べたらレンダリング深淵に飲まれた #レバテックMeetup
bengo4com
0
190
Tinkerbellから学ぶ、Podで DHCPをリッスンする手法
tomokon
0
150
Featured
See All Featured
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Chasing Engaging Ingredients in Design
codingconduct
0
89
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
0
67
What's in a price? How to price your products and services
michaelherold
246
13k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
130
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
860
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
200
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.3k
Exploring anti-patterns in Rails
aemeredith
2
210
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
74
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
73
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
115
94k
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