2012-05-10 64 views
10

以同样的方式大部分网站登录的工作,我是来存储“用户名”,在数据库中,但让用户以“用户名”登录。设计:允许用户注册的“用户名”,但与“用户名”

这是一个相当明显的和必要的功能,并且很多人似乎都问了,但我一直在磕磕绊绊的解决方案似乎从设计自己的文档断开。

例如,考虑这个博客帖子:http://anti-pattern.com/2011/5/16/case-insensitive-keys-with-devise

[...]你可能碰到一些用户喜欢在他们的登录(电子邮件和/或用户名输入 某些字母的问题)在大写, 但预计当他们尝试登录它是区分大小写的。一个不 不合理的要求[...]

酷!这就是我想要的。

他的解决方案:

# 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 ] 

特别:“这些键会在创建/修改用户downcased。”换句话说,用户名在数据库中被降低。

验证:

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

我思念的东西非常明显?

回答

10

devise wiki:你需要覆盖色器件的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一部分,如果你不需要通过电子邮件身份验证过。

这样你就不需要在case_insensitive_keys中列出username并且它不会在数据库中被降低。

+0

这当然如果你宣布将只工作:在用户登录模型虚拟属性,将其设为您的色器件:authentication_keys => [:登录]并使用您的登录表单属性。 –

+6

也,虽然你允许在数据库中的情况下,敏感的入口,你想确保独特之处是不区分大小写的,否则,你让这两个“用户名”和“用户名”,但第一个找到下将conflfate他们检索。所以添加validates_uniqueness_of:username,:case_sensitive => false –

+0

Works。另外,好建议,viktor。 – danneu