Я использую devise, omniauth и client-side-validation, как описано в ryan bates railscasts.
Теперь у меня проблема с проверкой пароля, которая должна быть пропущена при регистрации через omniauth третьей стороной.провайдер.
Регистрационная форма (html.erb):
Регистрация
Регистрация через сторонние сети
<% = form_for (resource,: as => имя_ресурса,: url => путь регистрации (имя_ресурса),: validate => true) do | f |%>
Зарегистрируйтесь напрямую
<% = f.label: имя%>> <% = f.text_field: имя%>> 1017 *
<% = f.label: фамилия%> <% = f.text_field: фамилия%>
<% = f.label: электронная почта%> <% = f.text_field: email%>
<% = f.label: пароль%> <% = f.password_field: пароль%>
<% = f.label: password_confirmation%> <% = f.password_field: password_confirmation%>
<% = f.submit "Зарегистрируйтесь сейчас ",: class =>" button-big "%>
<% end%>
Моя пользовательская модель имеет - см. ОБНОВЛЕНИЕ ниже
validates :password, :presence => true, :confirmation =>true
предложение и пароль_ требуется?определение
def password_required?
(authentications.empty? || !password.blank?)
end
Когда я регистрируюсь через стороннего провайдера omniauth, корректно отображается форма регистрации, и пользователю предлагается ввести адрес электронной почты.К сожалению, пользователь должен ввести пароль, хотя он не должен запрашиваться из-за регистрации через стороннего разработчика.
Кто-нибудь может подсказать, как это сделать?
Спасибо и наилучшими пожеланиями
Ян
ОБНОВЛЕНИЕ: чтобы дать более конкретное представление, я добавил еще несколько фрагментов кода
AuthenticationsController:
class AuthenticationsController < ApplicationController
def index
@authentications = current_user.authentications if current_user
end
def create
omniauth = request.env["omniauth.auth"]
authentication = Authentication.find_by_provider_and_uid(omniauth['provider'], omniauth['uid'])
if authentication
flash[:notice] = "Signed in successfully."
sign_in_and_redirect(:user, authentication.user)
elsif current_user
current_user.authentications.create(:provider => omniauth['provider'], :uid => omniauth['uid'])
flash[:notice] = "Authentication successful."
redirect_to authentications_url
else
user = User.new
user.apply_omniauth(omniauth)
if user.save
flash[:notice] = "Signed in successfully."
sign_in_and_redirect(:user, user)
else
session[:omniauth] = omniauth.except('extra')
redirect_to new_user_registration_url
end
end
end
def destroy
@authentication = current_user.authentications.find(params[:id])
@authentication.destroy
flash[:notice] = "Successfully destroyed authentication."
redirect_to authentications_url
end
end
RegistrationsController: class RegistrationsController
def create
super
session[:omniauth] = nil unless @user.new_record?
end
private
def build_resource(*args)
super
if session[:omniauth]
@user.apply_omniauth(session[:omniauth])
@user.valid?
end
end
end
Модель пользователя: класс User
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable,
:validatable, :email_regexp => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
# Setup accessible (or protected) attributes for your model
attr_accessible :firstname, :lastname, :email, :password, :password_confirmation, :remember_me
# validations
validates :firstname, :presence => true
validates :lastname, :presence => true
validates :email, :presence => true, :uniqueness => true
validates_email :email
validates :password, :presence => true, :confirmation =>true
# omniauth reference 3rd party
def apply_omniauth(omniauth)
if self.firstname.blank?
self.firstname = omniauth['info']['first_name'].presence || omniauth['info']['name'].presence || " "
end
if self.lastname.blank?
self.lastname = omniauth['info']['last_name'].presence || omniauth['info']['name'].presence || " "
end
if self.email.blank?
self.email = omniauth['info']['email'].presence
end
authentications.build(:provider => omniauth['provider'], :uid => omniauth['uid'])
end
# omit validation for omniauth session
def password_required?
(authentications.empty? || !password.blank?) && super
end
end
Аутентификация Класс модели Аутентификация
# Setup accessible (or protected) attributes for your model
attr_accessible :user_id, :provider, :uid
end
Во время отладки я обнаружил, что метод authentications.build () в методе apply_omniauth (omniauth) создает пустой объект, так что password_required?всегда имеет значение true и пароль должен быть предоставлен.
ДОПОЛНИТЕЛЬНЫЙ ВОПРОС: почему «authentications.empty?»всегда возвращать «ложь»?
Заранее спасибо
Ян