检查电子邮件是否已在以下if语句(Rails)中获取?

时间:2012-11-06 04:23:11

标签: ruby-on-rails ruby if-statement omniauth

我有以下行动:

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不是空白,请将他登录,并将其重定向到他的个人资料(如果他的idnil,请将其保存。换句话说,如果他没有尚未创建。)
  • 如果用户的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)部分?

3 个答案:

答案 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}') 

但我没有测试过这个。