1

我有以下动作:

用户.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

现在的代码:

用户.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)部分?

4

3 回答 3

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
于 2012-11-06T04:45:41.910 回答
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
于 2012-11-06T04:56:50.990 回答
0

不确定您是否需要 rails 答案或 SQL 答案,但您可以使用以下 SQL 来查找您的回复:

select id from users where email = :email 

如果返回 0 行,则电子邮件不存在,如果返回 1,则电子邮件确实存在。我想你也可以使用

Users#find(:first, :conditions => 'email = #{email}') 

但我没有测试过这个。

于 2012-11-06T04:36:29.360 回答