2016-12-06 88 views
0

我已經在設計之上使用Google,Linkedin,DropboxGithub設置了更簡單的社交用戶認證。

的Dropbox認證不起作用,而是給出了回調URL
http://localhost:3000/users/auth/dropbox/callback)的錯誤:Rails 4:用戶身份驗證 - NoMethodError

NoMethodError in Users::OmniauthCallbacksController#dropbox 
undefined method `first' for nil:NilClass 

問題:用戶模型(8號線)


我的代碼:

回調控制器:

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController 

    def all 
     user = User.from_omniauth(env['omniauth.auth'], current_user) 
     if user.persisted? 
      sign_in user 
      flash[:notice] = t('devise.omniauth_callbacks.success', :kind => User::SOCIALS[params[:action].to_sym]) 
      if user.sign_in_count == 1 
       redirect_to edit_user_registration_path 
      else 
       redirect_to root_path 
      end 
     else 
      session['devise.user_attributes'] = user.attributes 
      redirect_to new_user_registration_url 
     end 
    end 

    User::SOCIALS.each do |k, _| 
     alias_method k, :all 
    end 

end 

用戶模型:

# omniauth Gem 
def self.from_omniauth(auth, current_user) 
    authorization = Authorization.where(:provider => auth.provider, :uid => auth.uid.to_s, 
             :token => auth.credentials.token, 
             :secret => auth.credentials.secret).first_or_initialize 
    authorization.profile_page = auth.info.urls.first.last unless authorization.persisted? 
    if authorization.user.blank? 
     user = current_user.nil? ? User.where('email = ?', auth['info']['email']).first : current_user 
     if user.blank? 
      user = User.new 
      user.skip_confirmation! 
      user.password = Devise.friendly_token[0, 20] 
      user.fetch_details(auth) 
      user.save 
     end 
     authorization.user = user 
     authorization.save 
    end 
    authorization.user 
end 

def fetch_details(auth) 
    self.email = auth.info.email 
    self.username = auth.info.name 
    self.avatar = URI.parse(auth.info.image) 
end 

我感謝每個幫助!提前致謝。

回答

1

要直接回答您的問題: undefined method "first" for nil::NilClass正在發生,因爲您正試圖在空的或零對象上調用方法first

這可能是在您的用戶模型中,您試圖從current_user中找到用戶。現在

if authorization.user.blank? user = current_user.nil? ? User.where('email = ?', auth['info']['email']).first : current_user #This will cause the error that you are describing if both the current_user is nil and there is no User whose email is auth['info']['email']

,有幾件事情錯。如果他們試圖登錄到你的應用程序,那麼在這個階段的current_user應該是未設置的。

你可以試試這個更改爲

user = User.where(email: auth['info']['email']).first_or_create

這將創造用戶的新實例,如果不與授權提供的電子郵件存在。 然後你就可以繼續

user.persisted? 其現有用戶返回true,false爲用戶的新實例

+0

我認爲這個問題是在用戶模式的第5行,因爲錯誤仍然存​​在後我結合了你的建議。它似乎爲Dropbox它以某種方式無法找到一個網址。 – jonhue

+0

所以,同樣的原則適用。你在'auth.info.urls'上調用'.first',這意味着它是空的或者不存在。在這一行之前使用pry或byebug來調試使用pry或byebug來停止你的程序並檢查auth是否實際返回,然後相應地調整你的代碼。 –