ruby 在Rails中验证空密码

tzxcd3kk  于 12个月前  发布在  Ruby
关注(0)|答案(3)|浏览(91)

我在User模型中添加了密码验证:

validates :password, presence: true
validates :password, confirmation: { case_sensitive: true }

但是当我想更新users上的其他字段时,这些验证会使事务无效,因为password不存在。
通过一些研究,我意识到如果password不存在,我可以跳过这些验证:

validates :password, presence: true, if: :validate_password?
validates :password, confirmation: { case_sensitive: true }, if: :validate_password?

def validate_password?
  password.present? || password_confirmation.present?
end

但是,现在当我提交一个空白密码和密码确认时,validate_password?返回false。我不太明白发生了什么,因为
@user.update_attributes(password_reset_edit_params)返回true
哪里
password_reset_edit_params<ActionController::Parameters {"password"=>"", "password_confirmation"=>""} permitted: true>
但里面

def validate_password?
  password.present? || password_confirmation.present?
end

passwordpassword_confirmation的计算结果为nil,而我的@user密码没有更新为空字符串。
我应该提到,我使用的是Bcrypt,@user.password实际上总是评估为nil,而password_digest是可用的。
那么解决办法是什么呢?最后,我想我的问题很简单:
当我不试图提交密码时,如何忽略密码验证,但在提交空字符串时也允许这些验证?
我突然想到,我可以在控制器中添加一个条件,不允许传递空字符串,但必须有一个整洁的方法来解决这个问题。
任何帮助都非常感谢。谢谢你,谢谢

tv6aics1

tv6aics11#

如果你使用Bcrypt和digest,你可以在你的模型中使用例如

has_secure_password
validates :password, length: { minimum: 8 }, allow_blank: true

在这种情况下,验证将仅用于设置和更改密码。
如果您不更改密码,则不需要输入密码。
另一种方式

validates :password, presence: true, on: :create
mu0hgdu0

mu0hgdu02#

在Rails中,你不是在验证参数,而是在验证模型。
不要“如果密码不存在,则跳过验证”。这就是验证的目的。验证是为了验证模型,而不是参数。如果模型的密码为空,并且密码是必需的,则模型无效。总是.
但是当我想更新用户的其他字段时,这些验证会使交易无效,因为密码不存在。
这不是因为密码不存在,而是因为User的示例中没有密码。它应该工作的方式是:
1.使用密码创建用户并验证:User.create(name: "Me", password: "something that isn't nil")
1.用户更新:User.update(name: "New name") # password is inside the model still so it is still valid
就是这样如果您希望用户能够拥有nil / empty密码,那么您不应该尝试在模型中放置存在验证。

esbemjvw

esbemjvw3#

最终,我只是在User模型上验证密码格式和确认:

validates :password,  confirmation: true,
                      length: {within: 6..40},
                      allow_blank: true

以及对照控制器中的空白密码/密码确认来净化输入数据。

if password_reset_edit_params[:password].blank? || password_reset_edit_params[:password_confirmation].blank?
      @user.errors[:password] << "can't be blank" if password_reset_edit_params[:password].blank?
      @user.errors[:password_confirmation] << "can't be blank" if password_reset_edit_params[:password_confirmation].blank?
      render 'edit'

相关问题