I am working with omniauth with Rails
and trying to get twitter, facebook and google hooked up for authentication but keep running into this error:
PG::Error: ERROR: duplicate key value violates unique constraint "index_users_on_email"
DETAIL: Key (email)=() already exists.
Here is my Authentication Controller:
class AuthorizationsController < ApplicationController
def create
authentication = Authorization.find_by_provider_and_uid(auth['provider'], auth['uid'])
if authentication
flash[:notice] = "Signed In Successfully"
sign_in authentication.user, event: :authentication
redirect_to root_path
else
athlete = Athlete.new
athlete.apply_omniauth(auth)
debugger
if athlete.save(validate: false)
flash[:notice] = "Account created and signed in successfully"
sign_in athlete, event: :authentication
redirect_to finalize_profile_path
else
flash[:error] = "An error has occurred. Please try again."
redirect_to root_path
end
end
end
def failure
render json: params.to_json
end
private
def auth
request.env["omniauth.auth"]
end
def resource(user_type)
user_type.downcase.to_sym
end
end
I think what is happening is that when the Athlete is created it is creating one with a blank email address and the unique key is failing... how could I get around this? I think I know how to fix this for Google integration but since Twitter doesn't return an email, this issue will not resolve itself
This is how I was able to get it working:
class AuthorizationsController < ApplicationController
def create
authentication = Authorization.find_by_provider_and_uid(auth['provider'], auth['uid'])
if authentication
flash[:notice] = "Signed In Successfully"
sign_in authentication.user, event: :authentication
redirect_to root_path
else
athlete = Athlete.new(email: generate_auth_email(params[:provider]) )
athlete.apply_omniauth(auth)
debugger
if athlete.save(validate: false)
flash[:notice] = "Account created and signed in successfully"
sign_in athlete, event: :authentication
redirect_to finalize_profile_path
else
flash[:error] = "An error has occurred. Please try again."
redirect_to root_path
end
end
end
def failure
render json: params.to_json
end
private
def auth
request.env["omniauth.auth"]
end
def resource(user_type)
user_type.downcase.to_sym
end
def generate_auth_email(provider)
return auth.info.try(:email) unless provider == "twitter"
return "#{auth.uid}@twitter.com" if provider == "twitter"
end
end
I create an email using the twitter uid with twitter.com being the domain since twitter does not return an email address
Hope this helps someone in the future