👏
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