Rails confirming that password_confirmation is present when the password is present or has been changed

I have the following user model:

class User < ActiveRecord::Base # Users table has the necessary password_digest field has_secure_password attr_accessible :login_name, :password, :password_confirmation validates :login_name, :presence=>true, :uniqueness=>true # I run this validation on :create so that user # can edit login_name without having to enter password validates :password,:presence=>true,:length=>{:minimum=>6},:on=>:create # this should only run if the password has changed validates :password_confirmation, :presence=>true, :if => :password_digest_changed? end 

These checks do not quite do what I hoped. You can do the following:

 # rails console u = User.new :login_name=>"stephen" u.valid? # => false u.errors # => :password_digest=>["can't be blank"], # => :password=>["can't be blank", "please enter at least 6 characters"]} # so far so good, let give it a password and a valid confirmation u.password="password" u.password_confirmation="password" # at this point the record is valid and does save u.save # => true # but we can now submit a blank password from console u.password="" # => true u.password_confirmation="" # => true u.save # => true # oh noes 

So I want the following:

  • password required to create must be 6 characters long
  • password_confirmation required to create must match password
  • user does not need to send a password when updating username
  • password cannot be deleted during update

Something bothers me, is that the rails cause a no method error if I use password_changed? unlike :password_digest_changed? in my verification password verification. I do not understand why.

So does anyone know what I'm doing wrong here?

+6
source share
1 answer

password not a column in the database, is it? Attribute only?

So there is no password_changed? method password_changed? that would be available if password was a column. Rather, you just need to check if password at all.

Sort of:

 validates :password_confirmation, :presence => true, :if => '!password.nil?' 

Although this solves the initial problem you are facing, it still will not do what you want, as it only checks for availability, and you need it to be present and match the password. Something like the following should work (combined with the above check).

 validates :password, # you only need presence on create :presence => { :on => :create }, # allow_nil for length (presence will handle it on create) :length => { :minimum => 6, :allow_nil => true }, # and use confirmation to ensure they always match :confirmation => true 

If you have not seen :confirmation before, this is a standard check that looks for foo and foo_confirmation and ensures that they are the same.

Please note that you still need to check for password_confirmation

+13
source

Source: https://habr.com/ru/post/899887/


All Articles