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(ユーザーが電子メールを入力できる場所) に送信します。

emailここで、既に取得されている場合にエラーをフラッシュし、ユーザーをリダイレクトする別の if ステートメントを追加します。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)ですか?

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、通常はそうです。
混乱している場合は、 User モデルに関数を作成して、次のように読みやすくすることができます

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 に答える