Search code examples
ruby-on-railsactiverecordoauthoauth-2.0google-oauth

find_or_create_by not finding, only trying to create


Using google oauth for a project. Had it working, but wanted to pull the profile picture to display in my app. Once I was able to display the picture, I logged out and tried to relog back in with the oauth. It is now telling me that the name and email have already been taken. I am using a find_or_create_by in my User model to find or create by the oauth credentials. I don't know what is causing this as it was working just a bit ago. And now, when I go back to how my code first was, it is not working period. Just giving me the errors bc of validations(trying to create a record instead of finding the record in the database.)

sessions#create

def create
    if params[:provider].present?
      @user = User.find_or_create_from_auth(request.env['omniauth.auth'])
      if @user
        session[:user_id] = @user.id
        flash[:notice] = "Logged in as #{@user.name}"
        redirect_to dashboard_path
      end

Users model-

def self.find_or_create_from_auth(auth)
    find_or_create_by!(provider: auth.provider, uid: auth.uid, password_digest: 'N/A') do |user|
      user.provider = auth.provider
      user.uid = auth.uid
      user.name = auth.info.name
      user.email = auth.info.email
      user.address = "123 ABC St"
      user.password = 'n/a'
      user.oauth_token = auth.credentials.token
      user.oauth_expires_at = Time.at(auth.credentials.expires_at)
      user.save
    end
  end

Appreciate any help, just not seeing the disconnect here.


Solution

  • This line:

    find_or_create_by!(provider: auth.provider, uid: auth.uid, password_digest: 'N/A') do |user|

    You only are considering the uid, provider and password_digest. But as your error says the name and email have already been taken. Which means that at your users database you have a unique constraint in both. So even when the uid and provider are different, you can't persist a new instance at DB if it matches with another existing record.

    So you can remove the unique constraint or add that validation to find_or_create_by