👏
Hotwire を使って Rails 6.1 の scaffold を SPA にしてみた
はじめに
DHH 兄貴が公開してくれた Hotwire 、Websocket でリアルタイム更新が反映できて便利だなと思いましたが、ちょっと触ってみたら、 get で画面遷移なしでHTMLを取得する時ってどうすればできるんだろう
と疑問が出てきたので、 rails g scaffold
の画面を SPA にしてみました。
Hotwire の基本については、公式のビデオと Hotwireでリアルタイムなチャットを作る を参考すればイメージできると思います。
結論
できたもの
- 入力フォームを index に直接に表示することで、SPA にできました
- bootstrap を導入して入力フォームを modal でやりたかったんですが、HTML が取得できたものの、
それを受けてから modal を表示する
ところがうまくできなかったので、諦めました
- bootstrap を導入して入力フォームを modal でやりたかったんですが、HTML が取得できたものの、
- SPA 対応のポイント
-
turbo_frame_tag 'post_form'
を活用すれば、ほぼ既存の view を変更せずにできる -
link_to
にdata: { turbo_frame: 'post_form' }
を付けることで、リンク先のレスポンスから、上記のturbo_frame_tag
と同じ HTML id (post_form
) の要素を入れ替えてくれる - https://github.com/blueplanet/hotwire-scaffold/blob/master/app/views/posts/index.html.erb
-
感想
-
hotwire-rails は、 turbo-rails と stimulus-rails の組み合わせの設定をしてくれただけで、メインの仕事をしてくれているのは
turbo-rails
-
turbo
は5種類の動きappend / prepend / replace / update / remove
だけ定義されていて、それ以外の動きはstimulus
で頑張ろう的な感じ - 更新系の処理をトリガーとして、view を更新する処理を broadcast すればよいですが、複数の処理が必要な場合、処理の順番をどう制限できるかは、まだ分かっていない
-
stimulus
は、まだ良くわかってない
よかったところ
-
turbo_frame_tag
とdata: { turbo_frame: 'post_form' }
と組み合わせるだけで、既存の scaffold で生成した view を SPA にすることができた -
turbo_stream_from
とbroadcast*
と組み合わせることで、修正系の結果をリアルタイムで反映できた
改善したいところ
- webpacker があると、
turbo_frame_tag
の中にある submit ボタンが Form submit のレスポンスが 200 になっているにもかかわらず disabled のままになっている事象がある- よって、できたものの rails project は、
--skip-javascript
で初期化しました - 調べきれてなかったんですが、
rails/ujs
との整合性がよくない感じ
- よって、できたものの rails project は、
- webpacker をなく、
rails/ujs
なくなり、form_with ... remote: true
系が使えなくなってしまうので、不便 -
ujs
がなくても、You can still use the data-confirm and data-disable-with.
と ドキュメントに書かれています が、できたものでは、scaffold で生成した delete link は動きませんでした。
まとめ
-
turbo を使えば、js を書かなくて済むよ
的な感じがありますが、turbo ならでは
のやり方は、慣れる必要がある -
ujs
やwebpacker
と併用できないため、既存プロジェクトへの導入はもうちょっと待つほうがよいかも
Discussion