- 更新日: 2016年11月22日
- Devise
Devise でユーザーがパスワードなしでアカウント情報を変更するのを許可
Devise のデフォルトのユーザーのアカウント情報変更画面(users#edit)では、ログイン済みのユーザーが自分のアカウント情報を変更するために、現在のパスワードを入力するのが必須となっています。これをパスワードなしで自分のアカウント情報を更新できるように変更します。
— 環境 —
rails 5.0.0.1
devise 4.2
【追記 2016/11/08】
Rails 5 + Devise 4 の環境での検証を行いました。また、当初の Devise::RegistrationsController#update をオーバーライドする方法よりも、Devise::RegistrationsController#update_resource をオーバーライドする方法のほうが簡単なので、それについて追記しました。
【追記ここまで】
— 記事初回公開時の環境 —
rails-4.0.1
devise-3.2.2
Devise::RegistrationsController#update_resource をオーバーライド
Devise では Devise::RegistrationsController#update の中で、Devise::RegistrationsController#update_resource が呼び出されており、その実装はデフォルトでは以下のようになっています。
1 2 3 |
def update_resource(resource, params) resource.update_with_password(params) end |
なので、カスタマイズしたコントローラー(例えば Users::RegistrationsController < Devise::RegistrationsController)で、以下のようにオーバーライドします。
1 2 3 4 5 |
protected def update_resource(resource, params) resource.update_without_password(params) end |
update_without_password は Devise で実装されており、パスワードなしで更新を行うメソッドです。このようにすると、行数の少ないカスタマイズでパスワードなしでユーザーのアカウント情報を更新できるようになります。ただし、これだとパスワード自体を更新できません。
なので、パスワードなしで更新を可能にするロジックを自力で実装する場合は、以下のように書く。
1 2 3 4 5 |
protected def update_resource(resource, params) resource.update_without_current_password(params) end |
update_without_current_password は自分で User モデル等に実装を行います。エントリー末尾で、パスワードなしでパスワード自体を更新できるようにする User#update_without_current_password の実装を紹介しています。
当初公開しました以下の方法でも可能ですが、上述で追記した update_resource をオーバーライドする方法のほうが簡単です。
Devise::RegistrationsController#update をオーバーライド
まず、devise-3.2.2/app/controllers/devise/registrations_controller.rb(class Devise::RegistrationsController < DeviseController)の update を、Devise カスタマイズ用の controller でオーバーライドします。 Rails で Devise のコントローラーをカスタマイズ | EasyRamble
app/controllers/users/registrations_controller.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
class Users::RegistrationsController < Devise::RegistrationsController # ... def update self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key) prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email) #if update_resource(resource, account_update_params) if resource.update_without_current_password(account_update_params) yield resource if block_given? if is_flashing_format? flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ? :update_needs_confirmation : :updated set_flash_message :notice, flash_key end sign_in resource_name, resource, :bypass => true respond_with resource, :location => after_update_path_for(resource) else clean_up_passwords resource respond_with resource end end end |
Devise::RegistrationsController#update から丸コピペして持ってきたのをちょっとだけ変更。コメントアウトしてる行です。
1 |
if update_resource(resource, account_update_params) |
↓
1 |
if resource.update_without_current_password(account_update_params) |
と変更。update_without_current_password は自分で実装。current_password がなくても、ログイン済みのユーザーが resource (User モデルのインスタンス) を update できるようにします。
User モデルに update_without_current_password を実装
app/models/user.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class User < ActiveRecord::Base #... # allow users to update their accounts without passwords def update_without_current_password(params, *options) params.delete(:current_password) if params[:password].blank? && params[:password_confirmation].blank? params.delete(:password) params.delete(:password_confirmation) end result = update_attributes(params, *options) clean_up_passwords result end end |
params.delete(:current_password) で current_password のパラメータを削除。if params[:password].blank? && params[:password_confirmation].blank? の行は、パスワード変更のためのパスワード入力フィールドとその確認フィールドの両者とも空の場合のみ、パスワードなしで更新できるようにするためです。
ビューで current_password のフォーム要素を削除
current_password のフォーム要素を削除、または if false で囲み出力させないようにする。
app/views/users/registrations/edit.html.erb
1 2 3 4 |
<% if false %> <div><%= f.label :current_password %> <i><%= t(".current_password_warning") %></i><br /> <%= f.password_field :current_password %></div> <% end %> |
以上で終了です。
- – 参考リンク –
- How To: Allow users to edit their account without providing a password
- ruby on rails – Devise update user without password – Stack Overflow
- Module: Devise::Models::DatabaseAuthenticatable — Documentation for plataformatec/devise (master)
- Devise の関連記事
- RailsのDevise認証機能での実装チェックリストまとめ
- Deviseで送信されるメールのfrom(送信者メールアドレス)を変更
- Facebook の OAuth 認証で OAuthException(191)エラー
- Rails Devise でパスワードリセットなどのメールテンプレート(Mailer ビュー)をカスタマイズ
- Rails + Devise 環境でのフレンドリーフォワーディング機能を修正
- Deviseでユーザー登録完了時にウェルカムメールを送信する
- Rails Devise でユーザーがプロフィール情報を更新後に元のページにリダイレクトさせる
- Rails Deviseの日本語化辞書ファイル(devise.ja.yml)
- Rails + Devise で admin ユーザー(管理者)を削除できないようにする
- Devise3.2.2 のデフォルト設定では、Rememberable の remember_token のカラムがないのでソースを解読してみた
- 初回公開日: 2014年3月7日
- 2件のコメント
参考になりました!
うまく動作したので、一安心です。
ありがとうございます!
もってぃさん、こんばんは。ご報告ありがとうございます。うまく動いて良かったです!
Devise は最初はちょっと難しいですけど、コツつかんで慣れるととても便利です^^