Ruby on rails Rails成功保存了\u secure\u密码,但随后给出了零密码-验证失败

Ruby on rails Rails成功保存了\u secure\u密码,但随后给出了零密码-验证失败,ruby-on-rails,bcrypt,Ruby On Rails,Bcrypt,我有一个用户模型,具有安全密码和验证:密码,状态:true 然后发生以下情况: $ rails console > u = User.create(name: 'user', password: 'password') => #<User id: ... > u.password => 'password' > u.save => true > exit 诀窍在于,使用has_secure_password,password实际上并不作为持久化

我有一个用户模型,具有
安全密码
验证:密码,状态:true

然后发生以下情况:

$ rails console

> u = User.create(name: 'user', password: 'password')
=> #<User id: ...
> u.password
=> 'password'
> u.save
=> true
> exit

诀窍在于,使用
has_secure_password
password
实际上并不作为持久化模型属性存在。只存在对原始密码进行加密处理;在这之后,它一直是
password\u digest
(这就是为什么
.password
在现有对象上返回
nil

Rails本身“欺骗”验证,只验证密码摘要的存在和长度

#通过检查密码是否正确,确保模型具有密码
#存在,因此这适用于新记录和现有记录。但是,
#当出现错误时,消息将被添加到password属性中
#以便最终用户能够理解错误消息。
验证do |记录|
record.errors.add(:password,:blank),除非record.password\u digest.present?
结束
验证密码的长度,最大值:ActiveModel::SecurePassword::允许的最大密码长度

当有明文密码要验证时,您的自定义验证在初始创建时可以正常工作。但在这之后,就没有密码了,因此您的状态检查失败(其他检查也不相关)。要解决此问题,您可以在密码验证中添加
on:create
,以便它们仅在新记录的情况下运行。

您不应该能够看到密码,这就是
的全部要点,它拥有安全的密码
,但它不应该给出
nil
如果出现问题,应该给出加密版本。但是我明白你的意思了,为什么我要得到密码?为什么我要运行
user.valid?
gives
false
user.error。消息
告诉我没有密码?@Eyeslandic你肯定是对的,验证问题是由于我的自定义验证,验证只在创建时设置(
on:create
)根据解决方案,问题已解决。thx
$ rails console
> u = User.find_by(name: 'user')
=> #<User id: ...
> u.password
=> nil
> u.valid?
=> false
class User < ApplicationRecord
    has_many :notes
    has_many :goings
    has_many :cafes, through: :goings

    has_secure_password
    has_secure_password validations: false

    validates_uniqueness_of :name, {message: "%{value} name already exist"}
    validates :email, presence: { message: "%{attribute} must be given" }
  validates :password, presence: {
    message: 'You must enter a password'},
        length: {minimum: 2,
        message: 'Your password must contain at least 2 characters'
    }
    validates :name, presence: { message: "%{attribute} must be given" }

    def self.from_omniauth(response)
        User.find_or_create_by(uid: response[:uid], provider: response[:provider]) do |u|
            u.name = response[:info][:name]
            u.email = response[:info][:email]
            u.password = SecureRandom.hex(15)
        end
    end
end