2012-05-10 5 views
10

Так же, как и большинство веб-сайтов, я должен был хранить «UsErNaMe» в базе данных, но разрешить пользователям входить в систему с «именем пользователя».Devise: Разрешить пользователям регистрироваться как «UsErNaMe», но логин с «username»

Это довольно очевидная и необходимая функция, и многие люди, похоже, ее просили, но решение, которое я продолжаю спотыкаться, кажется, отключено от собственной документации разработчика.

Например, рассмотрим этот блог: 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 часть, если вам не нужно AUTH по электронной почте тоже.

Таким образом, вам не нужно указывать username в case_insensitive_keys, и он не будет сбрасываться в базу данных.

+0

Это, конечно, будет работать только в том случае, если вы объявили виртуальный атрибут входа в пользовательскую модель, установите это как ваш метод: authentication_keys => [: login] и используйте этот атрибут в своей форме входа. –

+6

также, хотя вы допускаете регистрационную запись в базе данных, вы хотите удостовериться, что уникальность нечувствительна к регистру, в противном случае вы разрешаете «имя пользователя» и «имя пользователя», но поиск сначала на нижнем будет конфликтовать их при поиске. Поэтому добавьте validates_uniqueness_of: имя пользователя,: case_sensitive => false –

+0

Работает. Также, хорошее предложение, виктор. – danneu

Смежные вопросы