【Rails】form_withでデータを送信する際にpostではなくgetを使った話

# はじめに
Railsで予約機能を作成していたら、データを保存しないときのform_withにはgetを使うべきかpostを使うべきか迷ったっため、HTTPメソッドについて改めて調べてみることにしました。

今回はgetを使うことにしたので、その理由とform_withからgetでデータを送信する際にURLがちょっとだけスッキリする記述方法について記録します。
私はこちらを予約機能で使用しましたが、検索機能にも使えそうです。

# 結論
### get
検索機能などによく使われる
ブックマークしたいときに使う
※今回の予約機能ではgetを使用

### post
パスワードなどの秘匿性の高い情報を送信するときに使用
IDなどをURLで指定できないようにしたいときも使える

# getとpostの違い
調べる前の私のgetへのイメージは、
* URLに内容が表示されるから重要なデータには使えない
* 複数のデータを送信するとURLが長くなって見た目が良くない
というようなざっくりしたイメージでした。

https://qiita.com/ryokky59/items/bba97cbfaa899b03e071

 getとpostについてなんとなくイメージできていると思っていたのですが、こちらの記事を読ませていただき、確かに、getの場合はブックマークが出来るという利点に改めて気づかされました。


# ちょっと寄り道…getを検索機能で使う
例えば、検索機能にgetを使えばタグやカテゴリなどのビューページを新たに作らなくても、検索時に生成されたURLを活用することでページが増えたように見せることが出来ます。

ビュー自体を増やしてカテゴリページを作ってしまうと管理が大変になってしまいますが、検索結果ページなら1つのビューだけで済みます。

もちろん、SEOの観点で言うと、ページ毎に合わせたコンテンツを追加することが出来なかったり、似たような表示のページが増えてしまうことで重複コンテンツとみなされてしまう場合もあるので使用には少し注意が必要です。

検索エンジンに引っかからないように、検索結果ページにはあえてnoindexタグを付けることもあります。

ただ、大手通販サイトなどは、検索結果ページが上位表示されているのを見かけることがあるので、もしかしたらサイトによっても対応は違うのかもしれませんが…。

# 本題…予約機能ではgetを使うことにした
今回私がやりたかったのは、
商品詳細ページから（show）
入力フォームページに進み（new）
確認画面を表示してから（confirm）
保存する。
という流れになっていて、showページから商品情報を送る際の記述を考えていたのですが、結局getを使うことにしました。

理由としては、
・送信したいデータは秘匿性の高い情報ではない
・URLからページの状態が分かりやすい
になります。

商品詳細ページに使用した実際の記述がこちらです。
```html:show.html.erb
<%= form_with url: new_pre_order_path, method: :get do |f| %>
  <%= f.hidden_field :item_id, value: @item.id %>
  <%= f.submit 'この商品を予約する', name: '', class: "btn btn-info p-2" %>
<% end %>
```
このページで「この商品を予約する」を押下したときのURL表示はこんな感じ…
```
https://……….com/pre_orders/new?item_id=1&commit=この商品を予約する
```
検索機能を作った際も似たような感じになっていたので、こんなものかなと思っていたのですが、URLをもう少しスッキリさせる方法をメンターの方から教えていただきました。

# getで送信する際にURLが少しだけスッキリする書き方
結論から言うと、「name: ''」を付け足すだけです。

先ほどのform_withの記述を見ていただくと、「この商品を予約する」の部分に「name: ''」を付けています。

```html:show.html.erb
  <%= f.submit 'この商品を予約する', name: '', class: "btn btn-info p-2" %>
```

この記述を追加するだけで、
```
https://……….com/pre_orders/new?item_id=1&commit=この商品を予約する
```
もともと上記のようになっていたURLの「&commit=この商品を予約する」が、
```
https://……….com/pre_orders/new?item_id=1
```
表示されなくなります。

どうしてこうなるんだろう…？と不思議に思ったので少し調べてみると、思ったよりも単純なことでした。

https://railsguides.jp/form_helpers.html#%E4%B8%80%E8%88%AC%E7%9A%84%E3%81%AA%E6%A4%9C%E7%B4%A2%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0

>検索フォームの作成には、以下のように、form_withとその中で生成されるフォームビルダーオブジェクトを使います。
<%= form_with url: "/search", method: :get do |form| %>
  <%= form.label :query, "Search for:" %>
  <%= form.text_field :query %>
  <%= form.submit "Search" %>
<% end %>
上のコードから以下のHTMLが生成されます。
<&#8203;form action="/search" method="get" accept-charset="UTF-8" >
  <&#8203;label for="query">Search for:</label>
  <&#8203;input id="query" name="query" type="text" />
  <&#8203;input name="commit" type="submit" value="Search" data-disable-with="Search" />
<&#8203;/form>

このように、Railsガイドにも記載されていますが、
__<%= form.submit "Search" %>__
を使用すると、
__<&#8203;input name="commit" type="submit" value="Search" data-disable-with="Search" />__
というHTMLが生成されます。

実際にform_withで記述したページをディベロッパーツールで確認すると、そのように変換されているのが分かります。
どうやら、Railsの記述がHTMLへ変換された際に「name="commit"」が付与され、「name: ''」を記述することでcommitの部分を上書きすることが出来たようです。

ちなみに、先ほどのshowページから飛ばしていたform_withでのsubmit部分をディベロッパーツールで見てみると、このような形になっていました。
```
<input type="submit" name="" value="この商品を予約する" class="btn btn-info p-2" data-disable-with="この商品を予約する">
```
やはりname属性の部分が空の状態になっています。

あまり意識していない部分だったので、指摘していただいて助かりました…！

# おわりに
name属性に関しては深く考えずにスルーしてしまっていたので、教えていただかなければ調べることもなかったように思います。
そもそも、Railsの書き方を学びながら学習を進めていくとうっかり忘れがちですが、ページとして表示される際はHTMLが生成されています。
そこのHTML表記という認識が抜けていてレイアウトに戸惑うことも時々あったので、きちんと意識して作業しようと改めて実感し、フォームの扱いに対する認識も改めることが出来ました。

最近ではデプロイ作業も入り、PumaにNginx、GitにAWSなど、学習を始めてからどんどん触れるツールが増えてきているので、作業の本質を見失わないように手順や要素の整理が必要だと感じています…！