1つのフォームを複数のHTTPメソッドで使い分ける方法です。
フォームオブジェクトで実装すると難しかったのでメモ。
他にもっと良い方法がある場合は遠慮なく教えていただけると嬉しいです
こんな方にオススメ
・フォームオブジェクトでフォームを実装している方。
・フォームで情報を送信する際に、新規作成と編集で同じフォームを使いたい方。
やることは2つだけ
(1) フォームを呼び出す側(render)に method: :〇〇を追加。(〇〇はpostやpatchなど)
(2) フォーム側に method: methodを追加。
###(1) フォームを呼び出す側
<%= render "フォームテンプレートのパス", url: 呼び出したいアクションのpath, method: :〇〇 %>
新規作成の場合は〇〇をpostに、編集の場合はpatch(put)にすればOKです。
###(2) フォーム側
<%= form_with model: モデルのインスタンス, url: url, method: method do |f| %>
普通はここでurlやmethodを直接指定すると思うのですが、あえて変数にしています。
そうすることで、新規作成でも編集でも使えるようにしています。
背景
renderでPATCHのパス(url)を定義したはずなのに、実際にはPOSTで送信されていることがありました。原因は下記の記事にあるように、フォームのmodel: に記述したインスタンスが既存であればPATCH, 既存でなければPOSTとなるからだと思われます。フォームオブジェクトを使うとフォーム送信のたびにインスタンスを生成するので、常にPOSTとなり期待した動きをしてくれません。そこで、methodも定義してこの問題を回避しています。
参考にした記事はこちら
環境
ruby: 2.7.1
rails: 6.0.3.3