Конфликты валидации в 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. Это похоже на тупик.

Я очень благодарен всем, кто поможет мне выбраться из этого лабиринта.

Спасибо.


person mRbOneS    schedule 01.01.2016    source источник


Ответы (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
person Amit Sharma    schedule 01.01.2016