case insensitive name, while preserving capitalization, in Devise

devise, ruby-on-rails, ruby-on-rails-3

Solution

What you might try is to not set `:name` as case insensitive, which will properly save the case-sensitive name in the database:

config.case_insensitive_keys = []

Then, override the `find_first_by_auth_conditions` class method on User to find the user by their name. Note that this code will vary depending on the database (below is using Postgres):

def self.find_first_by_auth_conditions(warden_conditions)
  conditions = warden_conditions.dup
  if login = conditions.delete(:login)
    where(conditions).where("lower(name) = ?", login.downcase).first
  else
    where(conditions).first
  end
end

Doing this, a `User.find_for_authentication(login: 'thefourthmusketeer')` will properly return the record with a `name` of "TheFourthMusketeer".

See https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address for an explanation of overriding this method.

Problem

Using a name as key, how do we validate the name when registering by ignoring case while still remembering the case when displaying? In `config/initializers/devise.rb`, setting `config.case_insensitive_keys = [ :name ]` seems to lowercase the entire name before registering. Example: some dude names himself TheFourthMusketeer. - The views will display TheFourthMusketeer, not thefourthmusketeer - No new user can register under, say, tHEfourthMUSKETEER

Original source