如何在Rails 3.2中使用has_secure_password时禁用密码/确认验证?

时间:2012-03-18 07:08:50

标签: ruby-on-rails validation activerecord ruby-on-rails-3.2

我有一个用户模型设置如下:

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

但我不希望在更新用户时运行密码和/或password_confirmation验证,除非用户正在尝试更改其密码。

因此,如果用户在未指定密码和/或确认的情况下更新表单中的信息,则应该成功。如果用户更新了他们的信息并包含密码和/或确认 运行的验证。

实现这一目标的最佳方法是什么?

2 个答案:

答案 0 :(得分:21)

您可以向两个验证器添加条件:if

选项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

选项2:

或者使用方法进行验证,将验证检查移到方法中,而不是单独的validates调用:

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

答案 1 :(得分:0)

除了Zabba的answer之外,选项1也可以这样写:

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