Search code examples
ruby-on-railsrubyauthenticationpassword-encryptionactioncontroller

Why password validation does not work after adding password recovery?


Faced a problem not clear to me. I used password validation during registration.

def pass_val
    if password_digest.count("a-z") <= 0 || password_digest.count("A-Z") <= 0 
      errors.add(:password, "must contain 1 small letter, 1 capital letter and minimum 8 symbols")
    end
  end
validates :password_digest, presence: true,
                            length: { minimum: 8 }

I made it possible to recover the password for the user, and validation just stopped working. I changed all password_digest in validation to just password and validation worked again. BUT, after that, password recovery disappeared, which began to curse for validation.

NoMethodError in PasswordResetsController#create
undefined method `count' for nil:NilClass

If I change all password again to password_digest, validation will disappear, but the recovery password will work again.

UPDATE

  1. Using password - validation in the console works (it also works on the site. Passwords recovery does not work).
  2. Using password_digest - validation in the console also works (it doesn’t work on the site, the recovery password works).

UPDATE 2 Moreover, an error occurs during password recovery when a letter is sent to the mail (before sending), and not exactly during the password change.

UPDATE 3 create method in PasswordResetsController:

def create
  author = Author.find_by_email(params[:email])
  author.send_password_reset if author
  flash[:success] = "Email sent with password reset instructions."
  redirect_to root_path
end

UPDATE 4 send password_reset:

  def send_password_reset
    confirmation_token
    self.password_reset_sent_at = Time.zone.now
    save!
    AuthorMailer.password_reset(self).deliver!
  end

But the letter is not sent, crashes up to this point. I want to emphasize that I either use password_digest in validation and validation does not work, and password recovery works. Or I use password in validation and validation works, but password recovery does not.

Also, it’s worth noting that the create method in PasswordResetsController is not used to change the password, but to send an email to the email. I can’t understand why validation swears at him.


Solution

  • The error was in the send_password_reset method. Added (: validate => false) to this method and it worked.

      def send_password_reset
        confirmation_token
        self.password_reset_sent_at = Time.zone.now
        save!(:validate => false)
        AuthorMailer.password_reset(self).deliver!
      end
    

    In vallidation i use password.