2012-05-10 55 views
10

ほとんどのWebサイトと同じように、データベースに "UsErNaMe"を格納していたが、ユーザー名は "username"でログインさせた。Devise:ユーザーが "UsErNaMe"として登録するが、 "username"でログインできるようにする

これはかなり明白で必要な機能ですが、多くの人がそれに尋ねているようですが、私が抱えている解決策はDevise自身のドキュメントと切り離されているようです。

例えば、このブログの記事を考える:http://anti-pattern.com/2011/5/16/case-insensitive-keys-with-devise

[...]あなたは、おそらく一部のユーザーが自分のログイン(Eメールおよび/またはユーザ名に 特定の文字を入力したい問題に遭遇しました

クール[...])大文字、 ではなくAではない 不当な要求。彼らはサインインしようとすると、それは大文字と小文字を区別しないことを期待!それが私が望むものです。

彼の解決策:

# config/initializers/devise.rb 
Devise.setup do |config| 
    config.case_insensitive_keys = [:email, :username] 
end 

私は発見を保つソリューションです。しかし、ここにその設定オプションのドキュメントがあります:

# Configure which authentication keys should be case-insensitive. 
# These keys will be downcased upon creating or modifying a user and when used 
# to authenticate or find a user. Default is :email. 
config.case_insensitive_keys = [ :username, :email ] 

特に: "これらのキーは、ユーザーの作成/変更時にダウンケースになります。"言い換えれば、ユーザー名はデータベース内でダウンケースされています。確認するには

User.create username: "UsErNaMe", password: "secret", email: "[email protected]" 
#=> <User username="username"...> 

私は痛いほど明らかに何かが足りないのですか?

答えて

10

devise wiki:モデル内でdeviseのfind_first_by_auth_conditionsメソッドを上書きする必要があります。

ActiveRecordの例:

def self.find_first_by_auth_conditions(warden_conditions) 
    conditions = warden_conditions.dup 
    if login = conditions.delete(:login) 
    where(conditions).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first 
    else 
    where(conditions).first 
    end 
end 

あなたも電子メールで認証を必要としない場合は、OR lower(email) = :value一部を除去することができます。

このようにusernamecase_insensitive_keysに記載する必要はなく、データベースにダウンケースされません。

+0

これは、ユーザーモデルで:login仮想属性を宣言し、それをあなたのdevise:authentication_keys => [:login]として設定し、その属性をログインフォームで使用する場合にのみ有効です。 –

+6

また、データベース内で大文字と小文字を区別できるようにするには、一意性が大文字と小文字を区別しないようにしたいと思うでしょう。そうでなければ 'Username'と 'username'の両方を許可します。したがって、validates_uniqueness_of:username、:case_sensitive => falseを追加してください。 –

+0

作品。また、良い提案、viktor。 – danneu