deviseでconfirmableモジュールを使っていると、メールアドレス変更時に確認メールが飛ぶような機能が追加されます。
動きとしてはユーザーのemailカラムを更新しようとすると
UPDATE "users" SET "updated_at" = ?, "confirmation_token" = ?, "confirmation_sent_at" = ?, "unconfirmed_email" = ? WHERE "users"."id" = ? [["updated_at", 2017-03-14 00:50:49 UTC], ["confirmation_token", "9oyvPM-eW36KzdEnEpWg"], ["confirmation_sent_at", 2017-03-14 00:50:49 UTC], ["unconfirmed_email", "kaetemiru@kaete.com"], ["id", 1]]
- confirmation_tokenが生成される
- emailカラムが更新される前に、unconfirmed_emailに一旦値が入る
ような挙動になります。
そして、送られていたメールのリンクにはこのconfirmation_tokenが埋め込まれます。
このtoken情報からuserを検索して、そのユーザーのemailを更新する流れです。
実際にリンクを踏むと以下のようなクエリが走り、emailが更新されます。
UPDATE "users" SET "confirmed_at" = ?, "unconfirmed_email" = ?, "email" = ?, "updated_at" = ? WHERE "users"."id" = ? [["confirmed_at", 2017-03-14 00:51:29 UTC], ["unconfirmed_email", nil], ["email", "kaetemiru@kaete.com"], ["updated_at", 2017-03-14 00:51:29 UTC], ["id", 1]]
これで無事emailが更新できました。
確認メールをskipしたい時はskip_reconfirmation!を使う
今回は都合上、確認メールを送らずにメールアドレスを変更したいケースが出てきました。
そんな時は既に用意されているskip_reconfirmation!
を使います。
userのmodelでインスタンスメソッドとして作成してみました。
def update_email self.email = unconfirmed_email self.unconfirmed_email = nil self.bounce_email = false skip_reconfirmation! save end
これでcontrollerでuser.update_email
で呼び出せば確認メールを送らずにemailが更新できます。
コメントを残す