ユーザーが意図的にパスワードを変更していないケースで、パスワード変更完了メールが送られると変なので、その処理の時だけ送らないようにしました。
結論は、Device側で用意されてたので、1行追加だけ。skip_password_change_notification!
Deviceの挙動
config/initializers/devise.rb で下記のようにtrueにすると、Deviceと関係ない所、パスワード変更してもメールが送られちゃいます。
after_updateでsend_password_change_notificationメソッドが呼び出されている為。
config.send_password_change_notification = true
ボツ案:skip_callbackを使う
保存処理の前に下記を追加。
確かに送られなくなるけど、他の所でも送られなくなる。
User.skip_callback(:update, :after, :send_password_change_notification)
保存処理の後に下記も追加。
何故か、違うユーザーに送られたような。。。
そもそも、並列で送信したい処理が走ったらどうなるんだろう。
危うさを感じるし、魔改造な気がしたので、別の方法を探す。
User.set_callback(:update, :after, :send_password_change_notification)
解決:フラグを発見
ググったりもするけど、最終的にはソースを読んでいる事が多い。挙動の理解もソースから。
~/.rvm/gems/ruby-3.0.0/gems/devise-4.7.3/lib/devise/models/database_authenticatable.rb
after_update :send_password_change_notification, if: :send_password_change_notification?
send_password_change_notification?って何してる?
if Devise.activerecord51? def send_password_change_notification? self.class.send_password_change_notification && saved_change_to_encrypted_password? && !@skip_password_change_notification end else def send_password_change_notification? self.class.send_password_change_notification && encrypted_password_changed? && !@skip_password_change_notification end end
@skip_password_change_notificationってもしかして。
def skip_password_change_notification! @skip_password_change_notification = true end
これが呼べれば良いので、saveする前に呼び出してみる。
@user.skip_password_change_notification! @user.save!
行けました。流石、Device。ちゃんと用意してくれてますね。
callback外すのとは違って、このモデルの値だけが対象なので、他に影響もでない。