user4584963
user4584963

Reputation: 2533

Devise skip confirmation when using omniauth

How can I change the following code so that a user that signs in with facebook gets to skip the confirmation with devise confirmable? I tried adding user.skip_confirmation! under the line user.email... but this did not work.

user.rb:

# Finds or creates user based on omniauth hash from given provider
  def self.from_omniauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
      user.provider = auth.provider
      user.uid = auth.uid
      user.first_name = auth.info.first_name
      user.last_name = auth.info.last_name
      user.email = auth.info.email
    end
  end

  # Overrides class method 'new_with_session' to persist and validate attributes
  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

omniauth_callbacks_controller.rb

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController

  def all
    user = User.from_omniauth(request.env["omniauth.auth"])
    if user.persisted?
      flash.notice = "Signed in!"
      sign_in_and_redirect user
    else  
      session["devise.user_attributes"] = user.attributes
      redirect_to new_user_registration_url
    end
  end
  alias_method :facebook, :all
end

Upvotes: 7

Views: 3198

Answers (2)

NZisKool
NZisKool

Reputation: 239

If you're looking for the simplest way, just adding user.skip_confirmation! in the method referred in the documentation does work now:

 # app/model/user.rb

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

    # Users are created if they don't exist
    unless user
      user = User.create(username: data['name'],
                         email: data['email'],
                         password: Devise.friendly_token[0, 20])
      user.skip_confirmation! # Add this line to skip confirmation
    end
    user
  end

If you want to skip both confirmation and the email confirmation notification (which would make sense), you'll just need to add user.skip_confirmation! before saving the user, which you can do like this:

 # app/model/user.rb

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

    # Users are created if they don't exist
    unless user
      user = User.new(username: data['name'],
                      email: data['email'],
                      password: Devise.friendly_token[0, 20])
      user.skip_confirmation! # Add this line to skip confirmation
      user.save
    end
    user
  end

Upvotes: 0

Bryan Dimas
Bryan Dimas

Reputation: 1452

Try this with first_or_initialize:

def self.from_omniauth(auth)
    where(provider: auth.provider, uid: auth.uid). first_or_initialize do |user|
      user.provider = auth.provider
      user.uid = auth.uid
      user.first_name = auth.info.first_name
      user.last_name = auth.info.last_name
      user.email = auth.info.email
      user.skip_confirmation!
      user.save!
    end
  end

Upvotes: 11

Related Questions