Конфликты валидации в Rails
Я работаю над проектом и столкнулся с проблемой, которую пытался решить, но безуспешно.
Все это произошло, когда я начал внедрять Forgot Password
функциональность для сброса пароля. у меня есть User Model
который имеет проверки для password
а также password_confirmation
, Я использовал их для регистрации и работаю нормально.
Но для этой функциональности я использую новый контроллер под названием PasswordResets
, Я генерирую строку с именем password_reset_token
для моей таблицы пользователей. И есть password_reset_sent_at
который записывает время, которое пользователь запрашивает для сброса. Процесс идет так:
1) Пользователь нажимает
Forgot Password
?2) Он перенаправлен на страницу, где его просят ввести свой адрес электронной почты.
3) Контроллер проверяет наличие электронной почты в базе данных, если да, то;
3.1) Я генерирую случайныйpassword_token
используяSecureRandom
а также время, когда он начал запрос.
3.2) Теперь происходит сохранение для отправки почты пользователю. Здесь проблема возникает.password_reset_token
не сохраняется в таблицу.
Причина в том, что я использую проверки для password
а также password _confirmation
в User.rb
, Здесь действие происходит :update
, поэтому при обновлении запись запрашивает password
а также password_confirmation
быть отправленным вместе с password_reset_token
и время.
Но я попытался решить, сохранив проверки как :on => :create
, теперь это работает хорошо, но когда я использую ссылку для сброса мои проверки не будет работать для password
а также password_confirmation
, Это как тупик для меня. Я знаю, что это немного сбивает с толку, я вставляю некоторый код, чтобы понять проблему.
мой PasswordResets Controller
создать действие:
def create
user= User.find_by_email(params[:email])
if user
user.send_password_reset
UserMailer.password_reset(self).deliver
flash[:success] = "Email sent with password reset instructions."
redirect_to root_url
else
flash[:error] = "Email doesn't exit."
render 'password_resets/new'
end
end
мой User Model
(User.rb)
class User < ActiveRecord::Base
has_secure_password
EMAIL_REGEX = /\A[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}\Z/i
validates_confirmation_of :password_confirmation
validates :username, :presence => true,
:uniqueness => true,
:length => {:within => 8..25}
validates :email, :presence => true,
:uniqueness => true,
:format => EMAIL_REGEX
validates :password, :length => {:within => 8..25}
validates :password_confirmation, :presence => true
def send_password_reset
generate_token(:password_reset_token)
self.password_reset_sent_at = Time.zone.now
save!
UserMailer.password_reset(self).deliver
end
def generate_token(column)
begin
self[column] = SecureRandom.urlsafe_base64
end while User.exists?(column => self[column])
end
end
Ошибка отображается на save!
в send_password_reset
, Я прилагаю изображение.
Я знаю, что проблему можно решить с помощью :on=>:create
для проверки как :update
запрос выполняется. Но когда я получаю ссылку подтверждения в моей консоли и использую ее, проверки пароля и пароля_контроля не работают, поскольку действие здесь :update
, Это как тупик.
Я действительно благодарен всем, кто выручил меня из этого лабиринта.
Спасибо.
1 ответ
Вы можете пропустить проверки, используя следующие, например.
def send_password_reset
generate_token(:password_reset_token)
self.password_reset_sent_at = Time.zone.now
self.save(validate: false)
UserMailer.password_reset(self).deliver
end