Search code examples
ruby-on-railsrubyvalidationrails-activerecordbcrypt

Validating against blank password in Rails


I added password password validations to my User model:

validates :password, presence: true
validates :password, confirmation: { case_sensitive: true }

but then when I wanted to update other fields on users, those validations were rendering the transaction invalid, as password was not present.

Through a bit of research, I realised that I could skip those validations if password wasn't present:

validates :password, presence: true, if: :validate_password?
validates :password, confirmation: { case_sensitive: true }, if: :validate_password?


def validate_password?
  password.present? || password_confirmation.present?
end

However, now when I submit a blank password and password confirmation, validate_password? returns false. I don't really understand what's happening, because

@user.update_attributes(password_reset_edit_params) returns true

where

password_reset_edit_params is <ActionController::Parameters {"password"=>"", "password_confirmation"=>""} permitted: true>

but inside

def validate_password?
  password.present? || password_confirmation.present?
end

password and password_confirmation evaluate to nil, and my @user password doesn't update to an empty string.

I should mention that I'm using Bcrypt, and @user.password actually will always evaluate as nil, whereas a password_digest is available.

So what is the solution? Ultimately I guess my question is simply:

How can ignore password validations when I'm not attempting to submit a password, but also permit those validations upon submission of an empty string?

It occurs to me that I could add a condition in the controller that doesn't allow empty strings to be passed, but there's gotta be a neat way to fix this issue.

Any help is much appreciated. Thanks!


Solution

  • If you use Bcrypt and digest, you can use in your model for example

    has_secure_password
    validates :password, length: { minimum: 8 }, allow_blank: true
    

    In this case validation will work only for setting and changing password.

    If you don't change password you don't need to enter password.

    Another way

    validates :password, presence: true, on: :create