Reputation: 1679
I was following this wiki to make user to login with their email OR username.
But I got error like this.
How can I fix it? My application controller is
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
skip_before_filter :verify_authenticity_token
after_filter :store_location
before_action :configure_permitted_parameters, if: :devise_controller?
def store_location
# store last url - this is needed for post-login redirect to whatever the user last visited.
return unless request.get?
if (request.path != "/users/sign_in" &&
request.path != "/users/sign_up" &&
request.path != "/users/password/new" &&
request.path != "/users/password/edit" &&
request.path != "/users/confirmation" &&
request.path != "/users/sign_out" &&
!request.xhr?) # don't store ajax calls
session[:previous_url] = request.fullpath
end
end
def after_sign_in_path_for(resource)
session[:previous_url] || root_path
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :password, :password_confirmation, :remember_me) }
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:login, :username, :email, :password, :remember_me) }
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:username, :email, :password, :password_confirmation, :current_password) }
end
end
My models/user.rb
looks like
class User < ActiveRecord::Base
has_many :hasuk_houses, dependent: :destroy
has_many :favorite_hasuk_houses
has_many :favorites, through: :favorite_hasuk_houses, source: :hasuk_house
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable,
:omniauthable, :omniauth_providers => [:facebook]
devise :validatable, :authentication_keys => [:login]
attr_accessor :login
validate :validate_username
def validate_username
if User.where(email: username).exists?
errors.add(:username, :invalid)
end
end
def email_required?
false
end
def login=(login)
@login = login
end
def login
@login || self.username || self.email
end
def self.find_for_database_authentication(warden_conditions)
conditions = warden_conditions.dup
if login = conditions.delete(:login)
where(conditions.to_hash).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first
else
where(conditions.to_hash).first
end
end
#facebook login
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
user.name = auth.info.name # assuming the user model has a name
end
end
def self.new_with_session(params, session)
super.tap do |user|
if data = session["devise.facebook_data"] && session["devise.facebook_data"]["extra"]["raw_info"]
user.email = data["email"] if user.email.blank?
end
end
end
end
Upvotes: 0
Views: 1433
Reputation: 4164
What you have up there is an error generated because the email you entered as already been used for another user in your database.
Now, this is a uniqueness validation error, which gets trigered when there is an attempt at duplicating a column with the uniqueness validation set.
There are different level of validations, there is the model validation, which you can set in your Model, and managed by Rails, and there is the database level validation.
The above is an example of a database level validation.
What you can do in this case is to set a corresponding Model level validation in your User Model:
#user.rb:
class User < ActiveRecord::Base
...
validates :email, uniqueness: true
...
end
This will provide another level of validation, which will be triggered by the app, and handled by the app, before giving control to the database.
You can now handle this validation anyhow you want.
Upvotes: 2