4
votes

NoMethodError (undefined method `persisted?' for nil:NilClass):

This is the error i get when trying to use omniauth with Devise...

I am able to signup for the site with facebook... but once i log out and try to log back in i get the

NoMethodError (undefined method `persisted?' for nil:NilClass):

class Models::OmniauthCallbacksController < Devise::OmniauthCallbacksController

def facebook # You need to implement the method below in your model (e.g. app/models/user.rb) @model = Model.find_for_facebook_oauth(request.env["omniauth.auth"], current_model)

if @model.persisted?
  flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Facebook"
  sign_in_and_redirect @model, :event => :authentication
else
  session["devise.facebook_data"] = request.env["omniauth.auth"]
  redirect_to new_model_registration_url
end

end

def passthru render :file => "#{Rails.root}/public/404.html", :status => 404, :layout => false # Or alternatively, # raise ActionController::RoutingError.new('Not Found') end

end

model.rb

class Model < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable,
  # :lockable, :timeoutable and 
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :omniauthable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :provider, :uid
  # attr_accessible :title, :body

  def self.find_for_facebook_oauth(auth, signed_in_resource=nil)
    model = Model.where(:provider => auth.provider, :uid => auth.uid).first
    unless model
    model = Model.create(name:auth.extra.raw_info.name,
                         provider:auth.provider,
                         uid:auth.uid,
                         email:auth.info.email,
                         password:Devise.friendly_token[0,20]
                         )
    end
  end


  def self.new_with_session(params, session)
    super.tap do |model|
      if data = session["devise.facebook_data"] && session["devise.facebook_data"]["extra"]["raw_info"]
        model.email = data["email"] if model.email.blank?
      end
    end
  end
end
2
Do you implemented find_for_facebook_oauth method in your model? Can you show it?Nick Kugaevsky
i did add that...im going through the omniauth wiki...i will post right nowuser1502223
any suggestions would be appreciateduser1502223

2 Answers

1
votes

Your find_for_facebook_oauth method is implicitly returning nil in cases where a model is found. You should explicitly return the model if it is found instead.

def self.find_for_facebook_oauth(auth, signed_in_resource=nil)
  model = Model.where(:provider => auth.provider, :uid => auth.uid).first
  return model if model
  model = Model.create(name:auth.extra.raw_info.name,
                         provider:auth.provider,
                         uid:auth.uid,
                         email:auth.info.email,
                         password:Devise.friendly_token[0,20]
                         )
end
1
votes
def self.find_for_facebook_oauth(auth, signed_in_resource=nil)
  model = Model.where(:provider => auth.provider, :uid => auth.uid).first
  unless model
  model = Model.create(name:auth.extra.raw_info.name,
                     provider:auth.provider,
                     uid:auth.uid,
                     email:auth.info.email,
                     password:Devise.friendly_token[0,20]
                     )
  end
  model #Add this here
end