質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Devise

Deviseとは、Ruby-on-Railsの認証機能を追加するプラグインです。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

1401閲覧

[devise]after_update_path_forメソッドをオーバーライドを有効にする方法

hypotest15

総合スコア20

Devise

Deviseとは、Ruby-on-Railsの認証機能を追加するプラグインです。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2022/01/30 04:55

編集2022/01/30 05:55

解決したいこと

ユーザー情報更新後、任意のページに遷移するようにしたい。
方法として、after_update_path_forメソッドをオーバーライドする。
メソッドGithub

起こっている問題

app/controllers/application_controller.rbで、
after_update_path_forメソッドをオーバーライドしたが、
呼びだされず、「/」に遷移してしまう。

確認した方法は、メソッド内にbinding,pryを記述し、処理を実行。
結果として、処理は止まらず、ルートページに遷移。
ユーザー情報の更新は、問題なく行えていた。

class ApplicationController < ActionController::Base before_action :configure_permitted_parameters, if: :devise_controller? private def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname]) devise_parameter_sanitizer.permit(:account_update, keys: [:nickname]) end def after_sign_in_path_for(resource) user_path(resource) end def after_update_path_for(resource) binding.pry # ここで処理が止まらなかった user_path(resource) end end

ルーティング

Rails.application.routes.draw do root to: 'xxx#index' devise_for :users resources :users, only: [:show] do resources :yyy, only: [:index] end end

調べたこと、考えたこと

上記binding.pryが機能しなかったことから、
オーバーライドしたメソッドが呼び出されず、
devise側のafter_update_path_forメソッドが呼び出されていると考えた。

まずは、メソッド名や利用方法を間違えたと考え調査。
こちらを見る限り、問題がないと判断。

また、下記の位置で処理をとめ、
コンソールで「after_update_path_for」を実行すると、
問題なく遷移させたいパスが返ってきた。

def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname]) devise_parameter_sanitizer.permit(:account_update, keys: [:nickname]) binding.pry end

以上から、作成したメソッド自体に問題はないと判断。


次に、オーバーライドのメソッドが呼び出せないため、
after_actionで呼び出す方式を試す。

class ApplicationController < ActionController::Base before_action :configure_permitted_parameters, if: :devise_controller? #after_actionで呼び出す after_action :after_update_path_for, only: :update, if: :devise_controller? private def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname]) devise_parameter_sanitizer.permit(:account_update, keys: [:nickname]) end def after_sign_in_path_for(resource) user_path(resource) end def after_update_path_for binding.pry #処理は止まり、呼び出せた  redirect_to user_path(resource) end end

無事に呼び出せたが、ダブルレンダーのエラーが発生。
これは、binding.pryを抜けたあとに、
devise側のafter_update_path_forメソッドが、
呼び出されている事が原因だと判断。

つまり、元のafter_update_path_forメソッドが呼び出されるのを
どうにかしないと解決できないと考えた。


その後、調査していると下記を設定するという記事を5本ほど見かけた。
参考記事例:[Rails]deviseのカスタマイズ。ユーザー登録、編集後のリダイレクトページを変える方法と、編集時のパスワード入力をスキップする方法

# routes.rb devise_for :users, controllers: { registrations: 'users/registrations' }

しかし、ログイン後の遷移先をオーバーライドする after_sign_in_path_for(resource)メソッドは、
上記を設定していなくても、問題なく機能していることから、
こちらの対処法は合わないと考えた。

また、こちらは、deviseコントローラーではなく、
devise管理化においたusersコントローラーでupdateをする用の対策ではないかと考えた。


なぜafter_sign_in_path_forは、オーバーライドでき、
after_update_path_forのオーバーライドしたメソッドが機能しないのか、
ご教授いただきたく存じます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

別の場所で下記URLと回答をいただき、解決しました。
How To: Customize the redirect after a user edits their profile

作業的な結論としては、
①RegistrationsControllerクラスを継承したRegistrationsControllerファイルを作成。
②ルーティングを変更。

# 変更前 devise_for :users # 変更後 devise_for :users, :controllers => { :registrations => :registrations }

以上で、無事オーバーライドしたafter_update_path_forメソッドが稼働しました。

問題としては、オーバーライドの基本を理解していなかったことが原因だと考えました。
オーバーライドとは、「継承した親クラスのメソッドの内容を子クラスで再定義すること」なので、
そもそも親クラスを継承しているか?
継承する親クラスは間違ってないか?、という点で躓いていました。

該当[メソッドはのクラス](https://github.com/heartcombo/devise/blob/main/app/controllers/devise/registrations_controller.rbは
class Devise::RegistrationsController であるため、
こちらのクラスを継承したコントローラーで記述しないと
deviseに関係ない「after_sign_in_path_for」という名前のメソッドを自作しただけ
という結果になっていたと考えます。

また、after_sign_in_path_forが稼働していのは、
こちらはモジュールとして定義されていたからだと推測します。
after_sign_in_path_for

devise Gemをインストールすると、モジュールが使えるようになっていて、
モジュールなので、applicationコントローラーで呼び出し、機能させることができたと考えました。

投稿2022/02/04 14:20

編集2022/02/04 15:03
hypotest15

総合スコア20

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問