Ответ 1
Чтобы использовать Devise с несколькими провайдерами auth, вам нужна еще одна модель - Авторизация
#authorization.rb
# == Schema Information
#
# Table name: authorizations
#
# id :integer not null, primary key
# user_id :integer
# provider :string(255)
# uid :string(255)
# token :string(255)
# secret :string(255)
# created_at :datetime
# updated_at :datetime
# profile_page :string(255)
#
class Authorization < ActiveRecord::Base
belongs_to :user
end
Существует код для Пользователь модели
#user.rb
SOCIALS = {
facebook: 'Facebook',
google_oauth2: 'Google',
linkedin: 'Linkedin'
}
has_many :authorizations
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.name = auth.info.name
self.email = auth.info.email
self.photo = URI.parse(auth.info.image)
end
И в конце вам нужно переопределить методы для контроллера Devise
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 first_login_path
else
redirect_to cabinet_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
Если вам нужны некоторые для поставщиков, например. Twitter вам нужно переопределить метод Twitter, потому что он не предоставляет пользователю электронную почту, и вы должны сохранить его credentails каким-то другим способом.
Также вы должны внести некоторые изменения в маршруты
devise_for :users,
:controllers => {
:omniauth_callbacks => 'users/omniauth_callbacks',
}