Deviseで特定のステータスのユーザーにログインさせない方法とエラーの日本語化(Rails)


Deviseを使っていたRailsアプリケーションで、ログイン情報としてIDとパスワードとは別に、特定の条件をユーザーが満たす場合にそのユーザーのログインを許可したくない場面があり、その際の制御と日本語表示を学んだので備忘として記載します。

やりたいこと

ユーザーはメールとパスワードでログイン可否の認証を行なっている。
しかしながら、ユーザーテーブルにはロック状態かどうかを判定するカラムがあり、ユーザーがロックされている場合にはログインさせたくない。
また、エラーメッセージを日本語化したい。

1. ユーザーにログインさせない方法

結論:Deviseが用意しているactive_for_authentication?メソッド を使う

user.rb
def active_for_authentication?
  super && active? # ユーザーがログインするためには、active?がtrueを返すことも必要
end

2. エラーメッセージの制御

結論:inactive_messageメソッドを使う

user.rb
def inactive_message
  active? ? super : :account_inactive # active?がfalseの時はdevise.
end

日本語化ファイル(devise.ja.yml)で日本語エラーを記載

devise.ja.yml
devise:
  failure:
    account_inactive: 'ロックされているためログインできません'

3. エラーメッセージに引数を渡したい

ユーザーカラムでは別でnameカラムを持っており、エラーメッセージは、例えばnameがrubyという人なら、
「rubyさんはロックされているためログインできません」といったエラーメッセージを表示したい。

結論:deviseのロケールではなく別のロケールで記述する

user.rb
def inactive_message
  # :account_inactiveから修正
  active? ? super : I18n.t('flash_message.inactive_user', name: name)
end

devise.ja.ymlの方に向ける方法で記載できるのかなーと思って試したり調べたりしましたが、出来なさそうだったので大人しくja.ymlに記載しました。
(こうやればできる、というのがあればぜひ教えてください)

ja.yml
ja:
  flash_message:
    # nameを受け取りたいなら%{name}と記載する
    inactive_user: "%{name}さんはロックされているためログインできません"

参考

ここまで書いて、この記事のほとんどは以下の記事に綺麗にまとめられていることを発見しました。
RailsのDeviseで特定の条件のアカウントをログインさせなくする