2012-05-10 63 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