Ruby - ActiveModel::SecurePassword 不工作

Ruby - ActiveModel::SecurePassword not working

我有一个包含 ActiveModel::ValidationsActiveModel::SecurePassword 的简单 ruby class,我向新对象提供了所有必需的属性(如下),但是当我验证它时它说它是 false.

require 'active_model'
require 'bcrypt'

class User
  include ActiveModel::Validations
  include ActiveModel::SecurePassword

  attr_accessor :name, :email, :password, :password_digest

  def initialize(name:, email:, password:)
    @name, @email, @password = name, email, password
  end
  
  validates :name, :email, presence: true
  has_secure_password
end

user = User.new(
          name: "TestUser1",
          email: "test@gmail.com",
          password: "password"
        )

puts user.valid? => false

puts user.errors.messages => {:password=>["can't be blank"]}

puts user.password => password

根据文档 here has_secure_password 提供对 password 访问器的验证:

  1. 密码应该存在。
  2. 密码应与其确认相同(前提是 password_confirmation 已传递)。
  3. 密码的最大长度为 72(ActiveModel::SecurePassword 所依赖的 bcrypt 要求)

我做错了什么?这个对象怎么是假的?

编辑 我也试过添加 password_confirmation 属性,但它也没有用。

user.password_confirmation = "password"

puts user.valid? => false

puts user.errors.messages => {:password=>["can't be blank"]}

我相信您还需要设置 user.password_confirmation 属性。

http://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html#method-i-has_secure_password

由于您需要 password_digestedActiveModel::SecurePassword 填充,因此您必须调用 User#password= setter method。但是当您在初始化程序中使用 @password = password 设置密码时,它不会发生。要修复它,您已使用 self.password = password:

进行设置
def initialize(name:, email:, password:) 
  @name, @email = name, email
  self.password = password
end

您还需要从 attr_accessor 调用中删除 :password,因为 SecurePassword 提供了它。