Search code examples
ruby-on-railsfacebookdeviseomniauthomniauth-facebook

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


I've looked up a few of the questions and answers here but couldn't find a solution to my problem. I keep getting undefined method `persisted?' for nil:NilClass when trying to login with Facebook. Here's my Omniauth callback controller:

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

Authorization Model:

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

and my User model:

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

I've tried quite a few things and still get that error. Can anyone point me in the right direction? Thanks a lot much appreciated!


Solution

  • I figured it out. Thanks! Just had to put validate false in the user.save to make sure it saved the info.