【Rails勉強ネタ】　HTMLのformは本当にGETとPOSTに制限されている？？

# きっかけ

書籍の**webを支える技術**を読んでいたら、p98に以下の記述がありました。

```
しかし、現実に一番よく利用されているのはGETとPOSTの2つです。
これはHTMLのフォームで指定できるメソッドがGETとPOSTだけという制限に起因します。
```
これを読んで、「だとすると、updateアクション(PATCHメソッド)はどうやって実現されるのだろう？？」
と思ったのですが、すぐ隣のページに書かれてました。
どうやらRailsは`_method` パラメーターを使って実現させているみたいです。

# 実際に確認してみる
お知らせを投稿できるNoticeというModelがあるとします。

###ルーティング
（当たり前ですが）updateアクションは`PATCH`か`PUT`で発動となっています。

```
$ rails routes|grep notice
     notices GET      /notices(.:format)                                                                  notices#index
             POST     /notices(.:format)                                                                  notices#create
  new_notice GET      /notices/new(.:format)                                                              notices#new
 edit_notice GET      /notices/:id/edit(.:format)                                                         notices#edit
      notice PATCH    /notices/:id(.:format)                                                              notices#update
             PUT      /notices/:id(.:format)                                                              notices#update
             DELETE   /notices/:id(.:format)                                                              notices#destroy

```

### HTML
editページのformを`右クリック→ページのソースを表示`で見てみます。

```
<form class="edit_notice" id="edit_notice_18" action="/notices/18" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="&#x2713;" />
  <input type="hidden" name="_method" value="patch" /><input type="hidden" name="authenticity_token" value="lGc0ypr/fV1WxhHZm6OS1ehZMpPj9IIgKF/8S5pm3FglyNHWxFgGLGt25AjoFb9BAINs4iRwg7VXn8eLjv9QGQ==" />
  <label>お知らせ</label>
  <textarea name="notice[body]" id="notice_body">test</textarea>
  <input type="submit" name="commit" value="登録" data-disable-with="登録中…" />
</form>
```

確かにformタグを見ると、 method="put" や method="patch"ではなく、 **`method="post"`** となっています。
そして、隠しパラメータ(hidden)に`_method`パラメータを用意しているのが確認できます。↓
**`<input type="hidden" name="_method" value="patch" />`**

# Wiresharkでパケットキャプチャーして見た
リアルなhttpパケットが見たいのでキャプってみました。
wiresharkでインターフェイスをlocalhostに指定してあげると、localhost:3000とのパケット通信をキャプチャーできます。

画像はeditページでsubmitした時のhttpパケットです。
<img width="1345" alt="スクリーンショット 2019-04-13 11.51.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251648/03e24e17-7af3-5160-8b43-51fff9e08492.png">

確かに**`POST` メソッドのHTTPリクエストが送信されている**ことが確認できます。

また、`HTML Form URL Encoded: application/x-www-form-urlencoded` 内で
`Form item: "_method" = "patch"`というパラメーターが確認できる。
おそらくこのパラメーターを見て**`"patch"`メソッドが送られたこととして処理している**んだと思われる（本当はPOSTメソッドを受け取っているが）。

# デバッグ
updateアクション内にbinding.pryを仕込んでデバッグ。

```
[1] pry(#<NoticesController>)> request
=> #<ActionDispatch::Request:0x00007fd6cb6156d0
 @env=
  {"CONTENT_LENGTH"=>"210",
   "CONTENT_TYPE"=>"application/x-www-form-urlencoded",
   "GATEWAY_INTERFACE"=>"CGI/1.1",
   "PATH_INFO"=>"/notices/15",
   "QUERY_STRING"=>"",
   "REMOTE_ADDR"=>"::1",
   "REMOTE_HOST"=>"::1",
   "REQUEST_METHOD"=>"PATCH",
   "REQUEST_URI"=>"http://localhost:3000/notices/15",
   "SCRIPT_NAME"=>"",
   "SERVER_NAME"=>"localhost",
   "SERVER_PORT"=>"3000",

```

実際に送信したHTTPリクエストは**POST**メソッドでしたが、Rails上では**PATCH**メソッドを受け取ったと認識して処理しているようです。
(`"REQUEST_METHOD"=>"PATCH"`)

#疑問に思ったこと
今回の確認では_methodでpatchが当てがわれているが、putはどのような条件で出てくるのだろう？？
（何かの条件でputのパターン、patchのパターンがあるのだろうか）