- 更新日: 2014年3月28日
- Rails
RailsでPOSTリクエストではリダイレクトできないことへの対応
Rails では POST リクエストによるリダイレクトができないようです。というか、HTTP protocol の RFC で定められていて、POSTリクエストではリダイレクトできないらしい。GETのみ。Stack Overflow に書いてありました。
ruby – redirect_to using POST in rails – Stack Overflow
— 環境 —
rails-4.0.1
devise-3.2.2
HTTP の POST メソッドによるリダイレクトはできなかった
想定したケースは、ログインしていないユーザーが、フォームのサブミットによる POST リクエストで複数ページを遷移している途中で、ログイン用ページに移動してログインした場合。この POST リクエストのページ遷移では DB に対する処理はなし。ショッピングカートのようにセッションに情報を保存させるだけです。
実現したかったことは、ユーザーがログイン後に、ログイン直前にいた POST リクエスト遷移の途中のページにリダイレクトさせたいと考えました。そこからユーザーが操作を再開できるようにしたいと。しかし…うーん、色々考えましたけど結局できませんでした。ログイン後のリダイレクトは GET リクエストになりルーティングエラーとなる。
セッションに POST リクエストのパラメータを保存
そこで、ログイン後に自動でリダイレクトさせる方法は諦めて、ログイン直前にユーザーがいたページの POST リクエストによるパラメータとアクションなどの情報を、セッションに保存して記憶することにしました。POST リクエストでページ遷移させるアクションに、以下を追加する。
some_controller/post_paging_action.rb
1 2 3 4 5 6 7 8 9 10 |
class SomeController < ApplicationController def post_paging_action session[:back_controller] = controller_name session[:back_action] = action_name session[:back_page] = params[:page].to_i ... end ... end |
遷移中ページのページ番号の情報 params[:page].to_i と、コントローラー名、アクション名を保存させました。
ログイン後にセッション情報からログイン直前のページ情報を復元
ログインした後に任意のページにリダイレクトさせます。ここでは、after_login_page_action にリダイレクトさせると仮定。このページで、ユーザーがログイン直前にいたページの情報をセッションから復元します。
some_controller/after_login_page_action.rb
1 2 3 4 5 6 7 8 9 10 |
class SomeController < ApplicationController def after_login_page_action @back_controller = session[:back_controller] @back_action = session[:back_action] @back_page = session[:back_page] ... end ... end |
続いてビューにフォームを作成して、ユーザーがログイン直前にいたページに移動できるようにしました。hidden filed に、ログイン直前にいた戻るべきページのページ番号を含ませて POST リクエスト送信します。
after_login_page_action.html.erb
1 2 3 4 5 6 |
<% if @back_controller && @back_action && @back_page %> <%= form_tag( { controller: @back_controller, action: @back_action}, method: :post) do %> <%= hidden_field_tag "page", @back_page %> <%= submit_tag "ログイン前のページヘ戻る" %> <% end %> <% end %> |
link_to に method: :post 指定では、なぜかURLにパラメータが付いてしまうので、フォームでページ移動させることにしました。ユーザーには、ログイン後に1クリックの負担をかけてしまいますが、一応これで妥協です。
戻ったページのビューでは、表示する情報はインスタンス変数、別途保存してあるセッション等から出力する必要があります。あと、必要に応じて、session[:back_controller] などのセッションは削除する。session[:back_controller] = nil などを必要なタイミングで。
- Rails の関連記事
- RailsでMySQLパーティショニングのマイグレーション
- Rails ActiveRecordでdatetime型カラムのGROUP BY集計にタイムゾーンを考慮する
- RailsプラグインGemの作成方法、RSpecテストまで含めたrails pluginの作り方
- RailsでAMPに対応するgemをリリースしました
- Railsでrequest.urlとrequest.original_urlの違い
- Railsでwheneverによるcronバッチ処理
- Google AnalyticsのRails Turbolinks対応
- Railsアプリにソーシャル・シェアボタンを簡単設置
- Rails監視ツール用にErrbitをHerokuで運用
- Facebook APIバージョンのアップグレード手順(Rails OmniAuth)
Leave Your Message!