先日、自社サービスのUX向上のために実施した内容を共有します。
やったこと
アカウントのemailアドレス変更完了メールを変更確定後に送るようにしました。
具体的には、設定画面で変更してから変更後のemailアドレスに送られる確定メールのリンクをクリックしたときに初めて、変更確定メールを変更前後のemailアドレスに送るようにしました。
やる理由
アカウント変更の前後で、変更前と変更後のアドレスにそれぞれメールを送れるようになると、アカウント変更の誤認識を防ぐことができます。
たとえば、全社員のアカウント管理を1人でやるというのは良く聞く話です。ITに詳しくない方がアカウント変更に戸惑ったりするのを防ぐために、専任の担当者にお任せするケースが多いです。
しかし、専任の方もITの専門家ではないことが多く、しかも他に業務を抱えていて多忙です。そんな中で手作業のメールアドレス変更は、作業の失敗リスクを高めます。
そういった状況に対応するため、アカウントが変更されたことを変更前と変更後のアドレスにそれぞれ送付して、チェックしやすくしました。
どうやるのか?
email変更はdeviseを使ってすでに実装しているので、こちらをカスタマイズして対応しました。
※ email認証機能の詳細は公式を参照ください。
変更1 deviseの設定を変更
emailの変更が発生したタイミング(内部的にはモデルクラスにupdateメソッドが実施されたタイミング)でemailを送信させないようにします。
config.send_email_changed_notification = false
変更2 モデルクラスを変更
deviseを実装したモデルクラスへ下記のメソッドを実装します。
protected
def send_email_changed_notification_to_new
send_devise_notification(:email_changed, to: email)
end
def after_confirmation
return unless saved_changes[:email].present? && saved_changes[:email][0] != saved_changes[:email][1]
self.unconfirmed_email = saved_changes[:email][0]
send_email_changed_notification
send_email_changed_notification_to_new
end
変更後のメールへ通知を送るメソッドを定義
変更確定(confirmメソッド発行)後にメールを送付するsend_email_changed_notification
は変更前のemailに送付するよう定義されています。こちらを参考にしながら、変更後のemailに送付するsend_email_changed_notification_to_new
を定義しました。
変更確定後のフックに、メール送信処理を定義
deviseのconfirmメソッドには、after_confirmation
というメソッドが定義されており、こちらに正常に変更が確定した後の処理を定義することができます。
このフックを利用して、ActiveRecord::AttributeMethods::Dirty#saved_changes
から変更前後のemailを取得してメールが変更されたかを判定しています。unconfirmed_email
はconfirmメソッドが正常に完了したタイミングでnilになるので、saved_changes
から変更前のemailを取得し、send_devise_notification
の処理に乗せてあげると変更前後のemailがメール本文に表示されるようになります。取得したunconfirmed_email
はDBに保存されないので、データが汚染されることはありません。
変更3 メール本文を変更
デフォルトでは変更前、変更後でメッセージが異なる設定になっています。こちらの条件分岐を外し、@resource
(deviseを実装したモデルクラスのインスタンス)から変更前後のemailを取得し、メール本文に表示します。
<p>ご要望の通り、アカウントに登録されているメールアドレスを変更しました。</p>
<p>ご登録のメールアドレスは <%= @resource.unconfirmed_email %> から <%= @resource.email %> に変更されました。</p>
以上で設定完了となります。
まとめ
小さい改善かとは思いますが、UX改善はコツコツやっていくのが大事だと思います。
その他
deviseでemailを送付したことをRSpecでテストしたいのですが、良い方法があれば教えてほしいです。