RailsのDeviseで特定の条件のアカウントをログインさせなくする

More than 1 year has passed since last update.


はじめに

DeviseをしようしているRailsのアプリケーションで、データベースにユーザーのレコードはあるがそのユーザーにはログインさせたくない時にする実装をする機会があった。はじめは authenticate_user! メソッドを上書きしようとしたが、少し調べた結果 active_for_authenticatation? というユーザーモデルのインスタンスメソッドを上書きするのが良いことに気づいた。以下に実際に特定の条件のユーザーのログインを不可にする実装とその際のエラーメッセージの設定の仕方を書いた。

参照:

How To: Customize user account status validation when logging in

Module: Devise::Models::Authenticatable


実装

例:

- Userモデルにデバイスをインストールしている

- 運営のメールに返信していないアカウントのログインを不可にしたい

- 運営のメールに返信したかどうかは users テーブルの mail_reply カラムが0か1で表されている


特定の条件のユーザーのログインを不可にする実装

DeviseのGithub Wikiページに に書いてあるとおりログイン時にバリデーションを足したい場合はUserモデルの active_for_authentication?を上書きします。このメソッドはログイン時にDeviseが呼び出しています。今回の例ではコードは以下のとおりになります。


user.rb

class User < ApplicationRecord

def active_for_authentication?
super && mail_reply?
end
end


エラーメッセージの変更

active_for_authentication? メソッドが false を返すと、Deviseは Account Not Active Error のメッセージを表示します。ですが、今回は「運営のメールに返信していないこと」を伝えたいので、独自のメッセージを表示したいです。

こちらにあるように、 active_for_authentication?false を返すと Userモデルのインスタンスメソッドの inactive_message を呼び出し、デフォルトでは Account Not Active のエラーメッセージを表示します。なので、inactive_message を上書きましよう。


user.rb

class User < ApplicationRecord

def active_for_authentication?
super && mail_reply?
end

def inactive_message
mail_reply? super : :mail_not_replied
end
end


デフォルトでは locales/device.en.ymlen.devise.failure.inactive のメッセージを表示するところを、運営のメールを返していない場合は en.devise.failure.mail_not_replied のメッセージを表示するようになります。日本語化をされている場合は locales/device.ja.ymlja.devise.failure.inactiveja.devise.failure.mail_not_replied になります。

ですが、現在は mail_not_replied のメッセージがないので追加してあげる必要があります。


英語の場合


locales/device.en.yml

# Additional translations at https://github.com/plataformatec/devise/wiki/I18n

en:
devise:
confirmations:
# 略
failure:
# 略
    # ここに追加
mail_not_replied: "Please reply mail from our company."
mailer:
# 略



日本語の場合


locales/device.ja.yml

# Additional translations at https://github.com/plataformatec/devise/wiki/I18n

en:
devise:
confirmations:
# 略
failure:
# 略
    # ここに追加
mail_not_replied: "運営からのメールを返信していません"
mailer:
# 略


上記のようにすると運営からのメールを返していないアカウントのログインを不可にできると思います。質問、コメント、指摘などあればコメントしていただけると幸いです。