【Rails5】ユーザパスワード更新の実装パターンまとめ
こんばんは
最近業務でRailsを使った社内用のアプリケーション開発を行なっていたのでそれについて何か書いてみます。
アプリケーションにユーザ管理機能を実装する際は、deviseというrubyのgemを使うことで簡単にユーザ管理に必要な機能を実装できます。 ユーザ情報への入力パラメータに対してバリデーションなどを簡単に実現できますが、独自に実装を加えたりする必要も場合によってはあります。 今回はdeviseを使ったユーザ管理を実装していく中で学んだこと、特にパスワードの更新周りで調べた点をまとめてみます。
rubyと各gemのバージョン
- ruby 2.5.1p57
- rails (5.2.1.1)
- devise (4.5.0)
パスワード更新のパターン
- ユーザ更新時にパスワードを更新しない
- ユーザ更新時に特定の条件でパスワードの検証をしない
- ユーザ更新時にパスワードフォームの値が空でない場合にパスワードを更新する
ユーザ更新時にパスワードを更新しない
ユーザ更新時にパスワードを更新したくない場合、strong parameterに:password
を含めない方法が簡単です。
params(:user).permit(:first_name, :last_name, :address)
上記は独自のコントローラー内でupdateを行う場合になりますが、Devise::RegistrationsControllerを実装したコントローラーに実装する場合は下記のようになります。 update_resourceをoverrideして中でupdate_resourceをresource.update_without_passwordを呼ぶように実装を変更します。
# app/controllers/registrations_controller.rb class RegistrationsController < Devise::RegistrationsController protected def update_resource(resource, params) resource.update_without_password(params) end end
ユーザ更新時に特定の条件でパスワードの検証をしない
deviseのvalidatableを実装することでupdate時にパスワードの検証を行うことができます。
class User < ApplicationRecord devise :validatable end
validatableのパスワード検証のロジックはpassword_required内で定義されています。
def password_required? !persisted? || !password.nil? || !password_confirmation.nil? end
このメソッドをoverrideすることで任意の条件でパスワード検証を行うことができます。
def password_required? if do_validate # パスワード検証を行う条件 !persisted? || !password.nil? || !password_confirmation.nil? else false end end
ユーザ更新時にパスワードの値が空だった場合、パスワードを更新しない
これは同僚から聞いて知ったのですが、controller内で参照できるparamsに含まれるパラメータは全てvalidationの対象となるようです。 なのでupdateメソッド内にパスワードが空だった場合、userをupdateする前にparams[:user].delete(:password)を実行することで validationを回避することができます。
def update if params[:user][:password].blank? params[:user].delete("password") end if @user.update(user_params) end
おわりに
それぞれ簡単にですがdevise利用を踏まえてのパスワード更新周りについてまとめました。 deviseは便利な機能が多いので使う場合はどんな機能があるのかをざっと確認しておくと良いです。 機能の全体像を把握する上で下記の記事が参考になりました。
[*Rails*] deviseの使い方(rails5版) - Qiita
参考リンク
rails: devise update user without password - CODE Q&A Solved