Created
April 5, 2012 10:32
-
-
Save pifleo/2309833 to your computer and use it in GitHub Desktop.
Rails - devise sign in by username or email - lib on user model
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# How To: Allow users to sign in using their username or email address | |
# https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-# app/views/devise/_links.html.haml | |
- if controller_name != 'sessions' | |
= link_to t("devise.shared.sign_in"), new_session_path(resource_name) | |
%br/ | |
- if devise_mapping.registerable? && controller_name != 'registrations' | |
= link_to t("devise.shared.sign_up"), sign_up_path | |
%br/ | |
- if devise_mapping.recoverable? && controller_name != 'passwords' | |
= link_to t("devise.shared.forgot_password"), new_password_path(resource_name) | |
%br/ | |
- if devise_mapping.confirmable? && controller_name != 'confirmations' | |
= link_to t("devise.shared.didnt_receive_confirmation_instructions?"), new_user_confirmation_path(resource_name) | |
%br/ | |
- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' | |
= link_to t("devise.shared.didnt_receive_unlock_instructions?"), new_unlock_path(resource_name) | |
%br/ | |
- if devise_mapping.omniauthable? | |
- resource_class.omniauth_providers.each do |provider| | |
= link_to t("devise.shared.sign_in_with_omniauth", :provider => provider.to_s.titleize), omniauth_authorize_path(resource_name, provider) | |
%br/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# lib/devise_by_login.rb | |
# Extension of user model to add :login field on devise | |
module DeviseByLogin | |
def self.included(base) | |
base.class_eval do | |
# attr_accessible | |
attr_accessible :login | |
# Virtual attribute for authenticating by either username or email | |
# This is in addition to a real persisted field like 'username' | |
attr_accessor :login | |
# ---------- Devise - connexion by username or email ---------- # | |
protected | |
def self.find_for_database_authentication(warden_conditions) | |
conditions = warden_conditions.dup | |
login = conditions.delete(:login) | |
where(conditions).where(["lower(username) = :value OR lower(email) = :value", { :value => login.strip.downcase }]).first | |
end | |
# Attempt to find a user by it's email. If a record is found, send new | |
# password instructions to it. If not user is found, returns a new user | |
# with an email not found error. | |
def self.send_reset_password_instructions(attributes={}) | |
recoverable = find_recoverable_or_initialize_with_errors(reset_password_keys, attributes, :not_found) | |
recoverable.send_reset_password_instructions if recoverable.persisted? | |
recoverable | |
end | |
def self.find_recoverable_or_initialize_with_errors(required_attributes, attributes, error=:invalid) | |
(case_insensitive_keys || []).each { |k| attributes[k].try(:downcase!) } | |
attributes = attributes.slice(*required_attributes) | |
attributes.delete_if { |key, value| value.blank? } | |
if attributes.size == required_attributes.size | |
if attributes.has_key?(:login) | |
login = attributes[:login] | |
record = find_record(login) | |
else | |
record = where(attributes).first | |
end | |
end | |
unless record | |
record = new | |
required_attributes.each do |key| | |
value = attributes[key] | |
record.send("#{key}=", value) | |
record.errors.add(key, value.present? ? error : :blank) | |
end | |
end | |
record | |
end | |
def self.find_record(login) | |
where(["username = :value OR email = :value", { :value => login }]).first | |
end | |
# ------------------------------------------------------------- # | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-# app/views/devise/passwords/new.html.haml | |
%h3= t("devise.shared.forgot_password") | |
= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f| | |
= devise_error_messages! | |
%div | |
= f.label :login | |
= f.text_field :login | |
%div.offset1= f.submit t("devise.passwords.send_reset_password_instructions") | |
= render "links" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-# app/views/devise/registrations/new.html.haml | |
%h3= t("devise.shared.sign_up") | |
= form_for(resource, :as => resource_name, :url => (resource && resource.usertype) ? "signup_#{resource.usertype}" : registration_path(resource_name)) do |f| | |
= devise_error_messages! if resource | |
%div | |
= f.label :username | |
= f.text_field :username | |
%div | |
= f.label :email | |
= f.email_field :email | |
%div | |
= f.label :password | |
= f.password_field :password | |
%div | |
= f.label :password_confirmation | |
= f.password_field :password_confirmation | |
%div.offset2= f.submit t("devise.shared.sign_up") | |
= render "links" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-# app/views/devise/sessions/new.html.haml | |
%h3= t("devise.shared.sign_in") | |
= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| | |
%div | |
= f.label :login | |
= f.text_field :login | |
%div | |
= f.label :password | |
= f.password_field :password | |
- if devise_mapping.rememberable? | |
%div | |
= f.check_box :remember_me | |
= f.label :remember_me | |
%div.offset2= f.submit t("devise.shared.sign_in") | |
= render "links" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-# app/views/devise/sessions/new.html.haml | |
%h3= t("devise.shared.sign_in") | |
= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| | |
%div | |
= f.label :login | |
= f.text_field :login | |
%div | |
= f.label :password | |
= f.password_field :password | |
- if devise_mapping.rememberable? | |
%div | |
= f.check_box :remember_me | |
= f.label :remember_me | |
%div.offset2= f.submit t("devise.shared.sign_in") | |
= render "links" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-# app/views/devise/sessions/new.html.haml | |
%h3= t("devise.shared.sign_in") | |
= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| | |
%div | |
= f.label :login | |
= f.text_field :login | |
%div | |
= f.label :password | |
= f.password_field :password | |
- if devise_mapping.rememberable? | |
%div | |
= f.check_box :remember_me | |
= f.label :remember_me | |
%div.offset2= f.submit t("devise.shared.sign_in") | |
= render "links" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/user.rb | |
class User < ActiveRecord::Base | |
include DeviseByLogin # lib/devise_by_login.rb | |
# Include default devise modules. Others available are: | |
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable | |
devise :database_authenticatable, :registerable, | |
:recoverable, :rememberable, :trackable, :validatable, | |
:token_authenticatable, :lockable, :timeoutable, :omniauthable, :confirmable #, :encryptable | |
... | |
# attr_accessible | |
# Setup accessible (or protected) attributes for your model | |
attr_accessible :username, :name, :first_name, :email, :password, :password_confirmation, | |
:remember_me, :terms_of_service #, ... | |
scope :confirmed, where('confirmed_at IS NOT NULL') | |
scope :unlocked, where('locked_at IS NULL') | |
scope :locked, where('locked_at IS NOT NULL') | |
scope :admin, where('admin') | |
... | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment