Reputation: 8261
I have a user model set up as such:
class User < ActiveRecord::Base
has_secure_password
# callbacks -------------------------------------------------------------------------
before_create { generate_token(:auth_token) }
# setup accessible (or protected) attributes for your model and validation ----------
attr_accessible :email, :password, :password_confirmation
# validations
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email , presence: true,
uniqueness: { case_sensitive: false },
format: { with: VALID_EMAIL_REGEX }
validates :password , length: { minimum: 6 }
validates :password_confirmation, presence: true
But I don't want the password and/or password_confirmation validations to run when updating the user unless the user is attempting to change their password.
So, if the user updates their information in a form without specifying a password and/or confirmation it should succeed. If the user updates their information and includes a password and/or confirmation the validations should run.
What is the best way to accomplish this?
Upvotes: 16
Views: 4910
Reputation: 115
In addition to Zabba's answer, option 1 could also be written like this:
with_options if: :password_provided? do
validates :password, :password_confirmation, presence: true, length: { minimum: 12 }
end
def password_provided?
password.present? || password_confirmation.present?
end
Upvotes: 0
Reputation: 65457
You could add a conditional :if
to both validators:
Option 1:
validates :password , length: { minimum: 6 }, :if => :validate_password?
validates :password_confirmation, presence: true , :if => :validate_password?
def validate_password?
password.present? || password_confirmation.present?
end
Option 2:
Or use a method for validation, moving the validation checks into the method instead of as separate validates
calls:
validate :check_password, :on => :update
def check_password
return unless password.present? || password_confirmation.present?
..validations for both attributes here..
..check presence, length etc. as required and add to the errors variable as necessary..
end
Upvotes: 21