🦁

【Ruby on Rails】Rails7.0以降のform_withでのlocal: trueの取り扱い

2024/07/07に公開

はじめに

今回は、パーフェクト Ruby on Rails 【増補改訂版】 (Perfect series) で学習を進めている中で、学んだ事項を簡単にまとめたいと思います。

パーフェクト Ruby on Rails 【増補改訂版】 (Perfect series)は、Rails6.0.3のバージョンでの内容となっており、現在のRails7系とバージョンもさほど離れていないので差異はそこまでないかな?と思い購入しましたが、表記の取り扱いでは大きく異なっていたため学習の備忘録として記載します。
参考になりましたら幸いです。

環境

  • Rails7.1.3.4

なぜ気がついたのか

p200の「手軽にAjax通信を行う」という項目にて、

ヘルパーメソッドのform_withはデフォルトでAjax通信を行う設定になっており、local: trueと明示することで通常の画面遷移になります。

との記載と、実際に検証ツールのネットワークタブの画像が載っており、local: trueの有無によってネットワークタブのtypeが変化していることが確認できました。
私自身、local: trueの取り扱いを理解していなかった部分があったので、実際に自分の手元で確認を行いました。
すると、本書の内容と異なる結果が表示されたのです...。
最初は自分の何らかのミスかな?と思いましたが、Railsガイドを確認したところv6.1とv7.0で記載が変わっていることに気がつきました。

自分で実際に手を動かすこと、また怪しいと感じた部分は公式ドキュメントを確認することの重要性を改めて感じた瞬間でした。

Rails7.1.3.4の環境で、local: trueをつけてみた

1、<%= form_with(model: @article, local: true) do |form| %>の場合
パーフェクト Ruby on Rails 【増補改訂版】 (Perfect series)内(Rails6代)では、typeが「document」になり、通常のHTTPリクエストが行われると記載がありましたが、HTTPリクエストは行われていません。(fetchになっていることが確認できます)

Image from Gyazo

2、<%= form_with model: @article do |form| %>の場合
次に、local: trueを外してみました。
Image from Gyazolocal: trueを外してみても、先ほどと変わりません。

Railsガイドの表記に関して

上記結果を受け、form_withのlocal: trueの取り扱いに関して変更があったのかな?と推測しました。
下記は、v6.1まで記載ありましたが、v7.0になると記載がなくなっておりました。
(command+Fで「local」で検索すると、v7.0で記載がなくなっていることが一発で確認できます)

Rails 6.0および5.2では、form_withを使うすべてのフォームはデフォルトでremote: trueを実装します。これらのフォームではXHR(Ajax)リクエストを使ってデータを送信します。これを無効にするには、local: trueを指定してください。詳しくはRails で JavaScript を使用するガイドを参照してください。

Rails7系の環境で、通常のHTTPリクエストを送るには?

上記の確認できましたが、通常のHTTPリクエストが行われるには、どう表記するのかわからずじまいだったため、
改めて確認しました。こちらの記事が簡潔にまとめられており、勉強になりました。

・ Rails7系では、Turboがデフォルトで有効になっていること
・ 通常のHTTPリクエストを行うには、<%= form_with model: @article, local: true, data: { turbo: false } do |form| %>を行うこと

実際に、手元のコードを<%= form_with model: @article, local: true, data: { turbo: false } do |form| %>に書き換えました。
Image from Gyazo

すると、通常のHTTPリクエストが行われました!

まとめ

直近のバージョン変更でも、大きく取り扱いが異なると改めて感じた事項でした。
今後もパーフェクト Ruby on Rails 【増補改訂版】 (Perfect series)は読み進めていきますが、
改めて鵜呑みにはせず、気になるコードは手元の自分のコードで確認しようと思います。
ありがとうございました。

参考

Discussion