Etienne
Etienne

Reputation: 261

Rails 3 + Devise 1.3.4: How to log in using a username?

I know there are tons of tutorials already that explain how to do that, but I've been spending way too much time trying to make it work without success...

Official doc: https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign_in-using-their-username-or-email-address

In the official doc they explain how to log in using the username OR email. I just want to log in using the username only.

What I've done:

1.  rails generate migration add_username_to_users username:string
2.  rake db:migrate
3.  rails generate devise:views

My app/models/user.rb: (I only added :username in attr_accessible)

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :username, :email, :password, :password_confirmation, :remember_me

end

My config/initializers/devise.rb:

 ...
 config.authentication_keys = [ :username ]
 ...

My app/views/devise/sessions/new.html.erb:

...
  <p><%= f.label :username %><br />
  <%= f.text_field :username %></p>
...

I believe this is all there is to change, but it will just say "invalid email or password".

Thank you for your help..!

Upvotes: 2

Views: 1721

Answers (3)

Krishna Satya
Krishna Satya

Reputation: 875

You have to change lines in config/locales/devise.en.yml. Change:

invalid:email or password  

To:

invalid:username or password

Upvotes: 1

David
David

Reputation: 7303

Add this to app/models/user.rb

def self.find_for_database_authentication(conditions={})
  self.where("username = ?", conditions[:username]).limit(1).first 
end

Upvotes: 0

Andi&#243;n
Andi&#243;n

Reputation: 1113

Have you overwrited find_for_database_authentication method like asked on the Devise documentation you provided?.

Something like this:

protected

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

Should make it work.

Upvotes: 1

Related Questions