問合せ画面から確認画面を表示させたかったが
沼ったので共有
rails7のこの事象についてQiitaの記事にもなかったので書いてみる
□状況
問合せ画面から確認画面へPOSTするが確認画面に遷移しない
サーバーのログ
Started POST "/contacts/confirm" for ::1 at 2024-05-15 00:22:22 +0900
I, [2024-05-15T00:22:22.287217 #8971] INFO -- : Processing by ContactsController#confirm as TURBO_STREAM
I, [2024-05-15T00:22:22.292437 #8971] INFO -- : Completed 400 Bad Request in 5ms (ActiveRecord: 0.0ms | Allocations: 808)
E, [2024-05-15T00:22:22.294219 #8971] ERROR -- :
ActionController::ParameterMissing (param is missing or the value is empty: contact):
もくもく会で師匠に質問したところturboが影響しているとのこと
参考記事
https://turbo.hotwired.dev/handbook/drive#redirecting-after-a-form-submission
https://stackoverflow.com/questions/70400958/error-form-responses-must-redirect-to-another-location
□解決
2つの方法があった
1、viewのform-withに「 data: { turbo: false } 」を指定
<%= bootstrap_form_with(model: @contact, url: confirm_contacts_path(@contact),
local:true, data: { turbo: false }) do |f| %>
2、 下記のようにコントローラーを修正
class ContactsController < ApplicationController
before_action :contact_params, except: :new
def new
@contact = Contact.new
end
def confirm
@contact = Contact.new(contact_params)
if @contact.valid?
render :confirm, status: 303 #ここを修正
else
redirect_to action: :new
end
end
...
end
解決方法1と2の違い
1 → URLが変更され画面遷移する
2 → URLは変更されず画面遷移する
2について
TurboはサーバーがHTTP 303 リダイレクトレスポンスを返すことを期待します
これまでの下記のような方法だとturboはレスポンスが合ってないよ〜
ってことで入力画面に戻ってしまうよう
def confirm
@contact = Contact.new(contact_params)
unless @contact.invalid?
render :confirm
end
end
解決!
turboは便利で強力だけど、クセをつかまないとね!
確認画面、インスタンスの状態について参考になった記事
https://qiita.com/ngron/items/d55aac6e81a9fb2fe81c
https://qiita.com/shimpex/items/0f9e9f9dfff648631c89