[Rails]postアクションでパラメーターをURLに含めずに送信して、ビューを表示させる方法
- 評価
- クリップ 1
- VIEW 511
ただいま、イベントを検索してチケットを購入できるアプリをRailsで作成しています。
ちょっと思ってたことができずに行き詰まってしまったので、、
もし良いアイディアがあれば教えていただけると嬉しいです!
実現したいこと
イベントのチケットを購入する際に、
申し込みフォームに名前やメールを入力して送信すると、
その後、フォームで入力したデータの「確認画面」が出てきて、
そこで確定ボタンを押して初めて購入処理がされるという、よくある機能を実現したいと思っています。
現在のコード
処理の流れは以下のような感じです。
①フォームに必要事項を入力させてpostメソッドで送信(※セキュリティの関係上getで送りたくない)
= form_with model: @guest, url: confirm_event_guest_path, method: :post, local: true do |f|
= f.text_field :name
= f.email_field :email
= f.submit "確認画面へ進む"
②アクションでparamsを受け取ったらrenderでビューを表示
def confirm
session[:guest] = guest_params
render action: "confirm"
end
private
def guest_params
params.require(:guest).permit(:name, :email)
end
③ルーティングは以下のようになっています
Rails.application.routes.draw do
root to: 'events#index'
resources :events do
resource :guest, module:"events" do
collection do
post 'confirm'
get 'done'
end
end
end
end
※関係のない部分は一部省略して書いています。
問題点
実は上記コードでもURLにパラメーターを含めずに送信できて、ビューも表示することができています。
しかしながら、ビューを表示した後にブラウザの更新ボタン(F5)を押すとルーティングエラーになってしまいます。
そもそもconfirmアクションはルーティングではpostになっているので、
更新ボタンを押したらgetを探しに行って「そんなルーティングないよ!」となるのはわかるのですが…。
今のところの候補
Ajaxで非同期通信で送る?
form_withだからダメでform_forならいける?
開発環境
ruby '2.5.1'
rails '5.2.2'
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+2
しかしながら、ビューを表示した後にブラウザの更新ボタン(F5)を押すとルーティングエラーになってしまいます。
通常、「購入処理中にリロードなど、ブラウザの機能を使った移動はしないでください」の注意書きで済ませます。
きちんと対応しようとすれば相応の工数がかかりますが、対応したことによるメリットがさほど見込めないので、往々にして省略されます。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
check解決した方法
0
解決方法を見つけたので共有します!
それはルーティングをgetとpostの2つ書くということです。
①同じconfirmアクションをgetとpostでルーティングに記述します。
Rails.application.routes.draw do
root to: 'events#index'
resources :events do
resource :guest, module:"events" do
collection do
post 'confirm'
get 'confirm'
get 'done'
end
end
end
end
②コントローラーではgetでもpostでも同じconfirmアクションが叩かれるので、
もし処理を分けたいならrequest.post?(またはrequest.get?)で分けます。
def confirm
if request.post?
session[:guest] = guest_params
render action: "confirm"
end
end
private
def guest_params
params.require(:guest).permit(:name, :email)
end
こうすることによってpostでパラメーターを送ることができ、
かつ、ブラウン座の更新ボタンが押されてgetでリクエストが飛んでもちゃんと表示されます!
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
関係ない設定を削るときに欠落しただけかもしれませんが、 do~end が不足しているように思えます
resource :payment, module:"guests" do
collection do
post 'confirm'
end
end
またAjax等に逃げても結局URL経由でのアクセスは変わらないので、URLが怪しいならまた問題が発生するでしょう
URL定義を確かめ根本の問題を解消すべきだと思います
routes.rb が実際にどんなURLになっているか確認してはどうでしょう?
bundle exec rake routes
※) 出力が多すぎて探しにくいなら grep で絞りましょう
bundle exec rake routes | grep payment
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.18%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
maisumakun
2019/04/24 15:36
では、「ビューを表示した後に更新ボタンを押」した場合、どのような動作をさせたいのでしょうか?
takuan1108
2019/04/24 16:19
ありがとうございます!
更新ボタンを押しても、ルーティングエラーにならず、
今いるページを再度表示させたいと思っています。
asm
2019/04/24 16:32
更新ボタンとは、ブラウザのいわゆるF5でしょうか?
それとも、ビュー側で「更新」と名のついたボタンを表示させているのでしょうか?
takuan1108
2019/04/24 16:59
説明不足ですみません!
ブラウザの更新ボタンのことになります。F5です。
今はルーティングがpostであるconfirmアクション内で、
無理やりrenderでビューを表示させるようにしているので、
ブラウザの更新ボタンではgetメソッドを探しに行ってしまってルーティングエラーになってしまうんです。。