Rails 使用 Devise 和 Omniauth 的社交登录 (Facebook) - 未定义的方法“持续存在?” nil:NilClass

Rails social login ( Facebook) with Devise and Omniauth - undefined method `persisted?' for nil:NilClass

我在这里查找了一些问题和答案,但找不到解决我的问题的方法。我不断收到未定义的方法“持续存在?” nil:NilClass 尝试使用 Facebook 登录时。这是我的 Omniauth 回调控制器:

class OmniauthCallbacksController < ApplicationController
  skip_before_filter :authenticate_user!

   def provides_callback_for
   user = User.from_omniauth(env["omniauth.auth"])
   if user.persisted?
    flash[:notice] = "You have signed in!"
    sign_in_and_redirect(user)
   else
    session['devise.user_attributed'] = user.attributes
    redirect_to new_user_registration_url
   end
  end
   alias_method :facebook, :provides_callback_for
end

授权模型:

class Authorization < ActiveRecord::Base
 belongs_to :user
 after_create :fetch_details_from_facebook

 def fetch_details_from_facebook
  graph = Koala::Facebook::API.new(self.token)
  facebook_data = graph.get_object("me")
  self.username = facebook_data["username"]
  self.save
 end
end

和我的用户模型:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :omniauthable
  has_many :friends
  has_many :notifications
  has_many :authorizations

  validates_presence_of :name
  validates :email, :presence => true, email_format: {message: "Please enter valid e-mail!"}
  validates :phone, phone: true, presence: true
  validates :birthday, :timeliness => {:on_or_before => lambda { Date.current }, :type => :date}

  def self.new_with_session(params, session)
    if session["devise.user_attributes"]
      new(session["devise.user_attributes", without_protection: true]) do |user|
        user.attributes = params
        user.valid?
      end
    else
      super
    end
  end


  def self.from_omniauth(auth)
    authorization = Authorization.where(:provider => auth.provider, :uid => auth.uid.to_s, :token => auth.credentials.token, :secret => auth.credentials.secret).first_or_initialize
    if authorization.user.blank?
      user = User.where('email = ?', auth["info"]["email"]).first
      if user.blank?
        user = User.new
        user.password = Devise.friendly_token[0, 10]
        user.name = auth.info.name
        user.email = auth.info.email
        user.image = auth.info.image
        user.save
      end
      authorization.username = auth.info.nickname
      authorization.user_id = user.id
      authorization.save
      end
    authorization.user
  end
end

我已经尝试了很多方法,但仍然出现该错误。谁能指出我正确的方向?非常感谢非常感谢!

已更新

请确认您收到的是来自 Facebook 的电子邮件。

未经批准,Facebook 不提供 EMAIL

请在 devise.rb

中添加范围 email

config/devise.rb

 config.omniauth :facebook, Settings.facebook.app_id, Settings.facebook.app_secret , { info_fields: 'email,first_name,last_name' , scope: 'email,public_profile' }

我想通了。谢谢!只需将 validate false 放入 user.save 以确保它保存了信息。