简体   繁体   中英

Omniauth not working: undefined method `persisted?' for nil:NilClass

Error Message Picture

I basically followed the instructions from the below link EXACTLY and I'm getting this damn error? I have no idea what I'm supposed to do, wtf? Do I need to create some kind of persisted method?? There were several other questions like this and after reading ALL of them they were not helpful at ALL. Please help.

https://github.com/zquestz/omniauth-google-oauth2

Omniauths Controller

class OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def google_oauth2
  # You need to implement the method below in your model (e.g. app/models/user.rb)
  @user = User.from_omniauth(request.env["omniauth.auth"])

  if @user.persisted?
    flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Google"
    sign_in_and_redirect @user, :event => :authentication
  else
    session["devise.google_data"] = request.env["omniauth.auth"].except(:extra) #Removing extra as it can overflow some session stores
    redirect_to new_user_registration_url, alert: @user.errors.full_messages.join("\n")
  end
  end
end

User model code snippet

def self.from_omniauth(access_token)
data = access_token.info
user = User.where(:email => data["email"]).first
# Uncomment the section below if you want users to be created if they don't exist
# unless user
#     user = User.create(name: data["name"],
#        email: data["email"],
#        password: Devise.friendly_token[0,20]
#     )
# end
  user
end

Changed the bottom portion to:

def self.from_omniauth(auth)
  where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
    user.email = auth.info.email
    user.password = Devise.friendly_token[0,20]
    user.name = auth.info.name   # assuming the user model has a name
 end
end

ran rails g migration AddOmniauthToUsers provider:string uid:string

Then it went to Successfully authenticated from Google account.

So I believe it works now. I think maybe the issue was I needed to add the provider and uid to the user database model?

The persisted? method is checking whether or not the user exists thereby returning nil value if no such record exists and your user model is not creating new ones. So by uncommenting the code from the example to this:

def self.from_omniauth(access_token)
  data = access_token.info
  user = User.where(:email => data["email"]).first

  # creates a new user if user email does not exist.
  unless user
    user = User.create(name: data["name"],
       email: data["email"],
       password: Devise.friendly_token[0,20]
    )
  end
 user
end

Should solve the problem of checking to see if the user exists or creating a new user.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM