我有以下行动:
users.rb的:
def omniauth_create
auth = request.env["omniauth.auth"]
user = User.from_omniauth(env["omniauth.auth"])
unless user.email.blank?
if user.id.nil?
# Save the user since he hasn't been created yet
user.save!
end
sign_in user
redirect_back_or user
else
# Send user to a form to fill his email
#session[:omniauth] = request.env['omniauth.auth'].except('extra')
redirect_to(enter_email_path(oprovider: user.provider,
ouid: user.uid,
oname: user.name,
opassword: user.password,
opassword_confirmation: user.password))
end
end
它执行以下操作:
email
不是空白,请将他登录,并将其重定向到他的个人资料(如果他的id
为nil
,请将其保存。换句话说,如果他没有尚未创建。)email
为空,请将其发送至enter_email_path
(用户可以在其中输入电子邮件地址)。现在我想添加另一个if语句,如果已经采用email
则会闪烁错误,并将用户重定向到root_path
我不太确定怎么做,有什么建议吗? (以及把if语句放在哪里?)
修改
奇怪,得到了这个而不是重定向到根路径:
Validation failed: Email has already been taken
我不知道这是否有帮助,但这里是from_omniauth
的起源:
def self.from_omniauth(auth)
find_by_provider_and_uid(auth["provider"], auth["uid"]) || User.create_with_omniauth(auth)
end
def self.create_with_omniauth(auth)
new do |user|
user.provider = auth["provider"]
user.uid = auth["uid"]
user.name = auth["info"]["name"]
user.email = auth["info"]["email"]
user.password = user.password_confirmation = SecureRandom.urlsafe_base64(n=6)
end
end
现在的代码:
user.rb :
# if user.email.present?
if user.id.nil?
# User.find_by_email(user.email).present?
if User.exists?(:email => user.email)
redirect_to root_path
end
user.save!
end
sign_in user
redirect_back_or user
else
(其余没有改变)。
似乎代码忽略了if User.exists?(:email => user.email)
部分?
答案 0 :(得分:4)
Rails有一种方法可以根据参数检查对象exists
。你可以这样做:
if user.email.present?
if user.id.nil?
if User.exists?(:email => user.email)
# return redirect email is already token
end
# save user
end
# sign_in user
else
# redirect to get email
end
顺便说一句,我不熟悉Omniauth所以我不确定什么是正确的,但是在检查对象是否已经保存时通常会使用new_record?
。如果您有id
,通常是。
如果您感到困惑,可以在用户模型中创建功能,以便更好地阅读
class User
def new?
id.nil?
end
def email_taken?
self.class.exists?(:email => email)
end
end
# back to controller
if user.email.present?
if user.new?
if user.email_taken?
# return redirect email is already token
end
# save user
end
# sign_in user
else
# redirect to get email
end
答案 1 :(得分:1)
试试这个
def omniauth_create
auth = request.env["omniauth.auth"]
user = User.from_omniauth(env["omniauth.auth"])
if user.email.present?
if user.id.nil?
if User.find_by_email(user.email).present?
# send error email already be taken
# or login with that user that means define that user for sign in
else
# save user and login with that user
user.save!
end
sign_in user
redirect_back_or user
end
else
# Send user to a form to fill his email
# session[:omniauth] = request.env['omniauth.auth'].except('extra')
redirect_to(enter_email_path(oprovider: user.provider,
ouid: user.uid,
oname: user.name,
opassword: user.password,
opassword_confirmation: user.password))
end
更新
您也可以使用find_or_create方法
def self.find_or_create(attributes)
Model.where(attributes).first || Model.create(attributes)
end
更新2
在您的模态文件中
class << self
def create_with_omniauth(auth)
create! do |user|
user.provider = auth['provider']
user.uid = auth['uid']
if auth['info']
user.uid = auth['uid'] || ""
user.name = auth['info']['name'] || ""
user.email = auth['info']['email'] || ""
user.access_token = auth['credentials']['token'] || ""
user.oauth_token_secret = auth['credentials']['secret'] || ""
user.oauth_token = auth['credentials']['token'] || ""
end
end
end
end
在您的控制器中
def create
auth = request.env["omniauth.auth"]
user = User.where(:provider => auth['provider'],:uid => auth['uid']).first || User.create_with_omniauth(auth)
session[:user_id] = user.id
redirect_to root_url
end
答案 2 :(得分:0)
不确定是否需要rails答案或SQL答案,但您可以使用以下SQL来查找答案:
select id from users where email = :email
如果返回0行,则电子邮件不存在,如果返回1,则确实存在。我猜你也可以用
Users#find(:first, :conditions => 'email = #{email}')
但我没有测试过这个。