フルカスタム方法
通常、#password=および#password_confirmation=単なる仮想セッターであり、真の属性は  #hashed_passwordまたは何かです。したがって、次のようなことができます。
class User
  attr_accessor :password, :password_confirmation
  validate :validates_password
  validates_presence_of :hashed_password
  private
  def validates_password
    if password or password_confirmation
      if password != password_confirmation
        errors.add( :password, 'your message' )
      end
      # your others validations
      self.hashed_password = hash_password
    end
  end
  def hash_password
    # your hashing code
  end
end
ユーザーがパスワードを提供して作成されるpasswordと、仮想属性password_confirmationが設定されるため、if条件が true になり、検証が適用されます。
パスワードがすでに設定されていて、ユーザーがそれを変更しない場合 (パスワードを提供しない編集フォーム)、検証は強制されませんif password and password_confirmation。
パスワードがすでに設定されていて、ユーザーがそれを変更してpassword設定するとpassword_confirmation、検証がトリガーされます。
パスワードをリセットしたい場合は、アクションhashed_passwordに nil を設定するだけです。モデルは現在無効でありvalidates_presence_of :hashed_password、ユーザーは新しいモデルを提供する必要があります。
#has_secure_password の使用
を使用#has_secure_passwordすると、レールはこれらのほとんどを処理します。特に:
- 仮想属性を作成します
 
- パスワード属性が提供されている場合にのみ、確認一致の検証をトリガーします
 
- パスワードをハッシュします
 
したがって、必要なのは独自の検証を追加することだけであり、存在する場合にのみ実行しpasswordますpassword_confirmation。
class User
  has_secure_password
  validate :validates_password
  private
  def validates_password
    if password or password_confirmation
      unless <your_test>
        errors.add( :password, '<your error message>' )
      end
    end
  end
end
以前と同様に、これは password と password_confirmation が提供された場合にのみトリガーされます。これは、ユーザーがそれらをフォーム データとして送信した場合にのみ発生します (実際の属性は ですpassword_digest)。