Конфликты валидации в 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
Другие вопросы по тегам