【Rails】【devise関連?】一定条件でかかるリダイレクト処理を一定画面だけ除外したい
解決済
回答 1
投稿
- 評価
- クリップ 2
- VIEW 1,524
今、以下のような新規登録フォームを作成しています。
①アカウント登録(メアド/Twitter)
②プロフィール設定
③登録完了
■仕様
①が完了した時点でUsersテーブルにデータが追加され実質ログイン状態となります。
①完了後、画面から離脱→再方→②から再開という場合に備えたい。
そのために、①が完了していて、②が完了していないユーザーがログインしてきた場合は、自動的に②の画面に遷移させています。
それが、ApplicationController内に以下のようなメソッドになります。
before_action :fix_user_sign_up_detail
▼ApplicationController
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :fix_user_sign_up_detail
before_action :store_current_location
before_action :configure_permitted_parameters, if: :devise_controller?
private
def fix_user_sign_up_detail
redirect_to edit_user_registration_detail_path if user_signed_in? && current_user.handle_name.blank?
end
def store_current_location
store_location_for(:user, request.url)
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys:[:email])
devise_parameter_sanitizer.permit(:sign_in, keys:[:login, :handle_name])
devise_parameter_sanitizer.permit(:account_update, keys:[:handle_name, :email, :password, :password_confirmation, :current_password])
end
end
ただ、これだと、②の画面に遷移した時にもリダイレクトがかかり、②の画面の無限ループに陥ります。
それを回避する施策で、Users::RegistrationsControllerにて以下のメソッドを追加しています。
prepend_before_action :authenticate_scope!, only: [:edit_detail, :update_detail]
class Users::RegistrationsController < Devise::RegistrationsController
prepend_before_action :authenticate_scope!, only: [:edit_detail, :update_detail]
# Twitter/メアドの選択画面
def select
end
# GET /resource/sign_up
def new
super
end
# ②の画面。名前やプロフィールを設定する。
def edit_detail
end
def update_detail
resource_updated = resource.update(detail_params)
if resource_updated
@modal = {name: 'update-detail-modal'}
end
render :edit_detail
end
protected
def detail_params
params.require(:user).permit(:icon, :handle_name, :profile)
end
# The path used after sign up.
def after_sign_up_path_for(resource)
edit_user_registration_detail_path
end
end
しかしながら、edit_user_registration_detail_path(②の画面。edit_detailアクションのViewです。)に遷移するとリダイレクトの無限ループになります。
これってそもそも、prepend_before_action :authenticate_scope!, only: [:edit_detail, :update_detail]の解釈が誤っていますか??つまり、リダイレクト(before_action :fix_user_sign_up_detail)を適用外にする効力は持っていない??
もし、その場合、どのような方法で、edit_detailとupdate_detailで無限ループに陥るのを回避出来ますでしょうか??
※before_action :fix_user_sign_up_detail,except:%w( edit_detail update_detail )でも回避出来る?と思いますが、あまり良い方法に思えず、これ以外の方法が知りたいのです。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
0
before_action の if: オプションを使う手もありますね。
class ApplicationController < ActionController::Base
before_action :fix_user_sign_up_detail, if: :needed
private
def needed
true
end
end
class Users::RegistrationsController < Devise::RegistrationsController
private
def needed
false
end
end
(メソッド名はもうちょっとマシな名前にしてあげてください)
①この方法でコントローラー毎ではなく、アクション毎のスキップは出来ないでしょうか?
できますよ。 #needed
をそのように実装してあげればいいだけです。
def needed
params[:action] != 'kino_action_ha_skip'
end
②結局のところ、prepend_before_action :authenticate_scope!, only: [:edit_detail, :update_detail] というメソッドでは、アクション毎にbefore_actionをskip出来ないのでしょうか??
before_action
は通常書く度に後ろに追加されていきますが prepend_before_action
は先頭に追加されていくというのが違いという風に思っています。
なぜskipするのに使えると思ったのかがわからないので、なんとも言えないですが、prepend_before_action
で登録済の action をキャンセルする方法は僕はわかりません。ごめんなさい。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 89.99%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2016/10/25 10:08
①この方法でコントローラー毎ではなく、アクション毎のスキップは出来ないでしょうか?
調べたところ、コントローラー毎で制御出来るのは理解出来ました。
https://blog.hello-world.jp.net/ruby/2637/
②結局のところ、prepend_before_action :authenticate_scope!, only: [:edit_detail, :update_detail] というメソッドでは、アクション毎にbefore_actionをskip出来ないのでしょうか??
2016/10/25 10:29
②のprepend_before_action :authenticate_scope!でskip出来るのかな?と思ったのは、以下の記事を見たからという安直なものでした・・・!
http://qiita.com/MasatoYoshioka@github/items/7de96ac05bc0c17b7535