POST リクエストがナビゲーションを目的としたものではないことは承知していますが、自分に課せられたことが可能かどうかを確認したいだけです。
Rails アプリにページがあります。それを cars#index と呼びます。このページで車を選択し、その選択内容を送信すると、car_sales の新しいページが表示され、選択内容が別のテーブルにリストされます。
車を選択できるテーブルがあり、このデータを POST して、以前に選択した車のリストを含む新しいページを car_sales#new にレンダリングしたいと考えています。
これも可能でしょうか?
# POST car_sales#new
def new
@cars = Car.where(id: selected_car_id_params)
respond_to do |format|
format.html
end
end
通常、作成アクションに POST すると、データベースに保存されている車をクエリする他のページにリダイレクトされます。ここでの違いは、まだ DB に永続化したくないことです。
cars#index ページからデータを POST するところまではできましたが、ネットワーク タブに返されるのは car_sales#new ページの HTML です。つまり、ブラウザは同じページに留まりますが、リダイレクトされません。
誰かがこれが起こる技術的な理由を説明できますか?
これが私のインデックス方法ですが、ここでは関係ないと思います:-
# GET cars#index
def index
@cars = Car.all
end
これは、POST ルートを追加するだけで非常に簡単に実現できます。
resources :car_sales do
post :new
end
# GET /car_sales/new
# POST /car_sales/new
def new
# @todo rewrite so it checks if param is present.
@cars = Car.where(id: selected_car_id_params)
respond_to do |format|
format.html
end
end
<%= form_with(url: new_car_sales_path, method: :post, data: { turbo: false }) do |form| %>
# ...
<% end %>
しかし、実際には「でもなぜ?」という疑問が生じます。冪等なフォーム送信には POST を使用する必要はありません。標準の GET ルートをそのまま使用できます。
フォームの送信に応じて何かを永続化することを強制するものは何もありません。それは単なる慣例です。また、追加の入力を使用してビューをレンダリングするだけなので、実際に何かを永続化する必要はありません。
実際に必要な場合 (実際に必要でない場合)、クエリ文字列またはセッションを通じてパラメーターを転送することもできます。
あなたは間違ったことを期待しています。フォームの送信によってリダイレクトは発生しません。これはサーバーへの GET/POST リクエストであり、サーバーは必要に応じてそれに応答できます。
あなたの場合、コントローラーは応答として暗黙的にビューをレンダリングし、デフォルトの 200 - OK ステータスコードを送信します。実際にリダイレクトが必要な場合 (必要ない場合)、サーバーは 3XX ステータス コードと場所ヘッダーで応答する必要があります。これは redirect_to で行います。
クライアントが新しいビューをレンダリングしない理由については、リクエストが XHR リクエストとして送信されているか、実際には正しいリクエストを送信していない、または自分が思っているものをレンダリングしていないのではないかと推測することしかできません。