新手问题 Model 中 validates 的验证可以设置只在特定动作里执行吗?

qq2729877005 · 2017年07月22日 · 最后由 qq2729877005 回复于 2017年07月22日 · 1417 次阅读
validates :password, confirmation: {message: "二次密码不一致"},
                                                        presence: {message: "密码不能为空"}
validates :password_confirmation, presence: {message: "二次密码不能为空"}
has_secure_password validations: false

这是我 User 模型中的局部代码,我把 has_secure_password 自带的验证给关了,自己定义验证方式。 而现在我在做用户资料更改功能,有部分数据是必须验证的,所以我是不能使用跳过验证的方式去更改的,但不跳过去的话, 这两个验证又过不去。我本想搞两个隐藏字段来传这两个数据的,然而我数据库中存的用户密码是经过 bcrypt 处理的, 所以目前只想到在控制器 update 动作中再做一遍验证,但这样做的话,感觉跟个傻逼似的,而且也违反了控制器与模型分离的原则。 各位大侠有没有好的办法啊?😭 😭

源码:

validates_confirmation_of :password, allow_blank: true

如果 password 为空就不校验,所以你不要传 password 参数(去掉表单项)就行。

Rei 回复

有考虑过,但这样做的话,注册时,用户不填密码或填" "都能通过了

找到解决方法了,在 rails 指南发现的💔 ,我竟然在 api 瞎忙活大半个早上😂 😂 😂 😂

qq2729877005 回复

并不会,我贴下完整代码:

# File activemodel/lib/active_model/secure_password.rb, line 53
def has_secure_password(options = {})
  # Load bcrypt gem only when has_secure_password is used.
  # This is to avoid ActiveModel (and by extension the entire framework)
  # being dependent on a binary library.
  begin
    require "bcrypt"
  rescue LoadError
    $stderr.puts "You don't have bcrypt installed in your application. Please add it to your Gemfile and run bundle install"
    raise
  end

  include InstanceMethodsOnActivation

  if options.fetch(:validations, true)
    include ActiveModel::Validations

    # This ensures the model has a password by checking whether the password_digest
    # is present, so that this works with both new and existing records. However,
    # when there is an error, the message is added to the password attribute instead
    # so that the error message will make sense to the end-user.
    validate do |record|
      record.errors.add(:password, :blank) unless record.password_digest.present?
    end

    validates_length_of :password, maximum: ActiveModel::SecurePassword::MAX_PASSWORD_LENGTH_ALLOWED
    validates_confirmation_of :password, allow_blank: true
  end
end

这一行:

record.errors.add(:password, :blank) unless record.password_digest.present?

如果 password_digest 不存在,就会报 password 为空,这样创建用户的时候校验通不过。

Rei 回复

老司机勿怪,我是新手,不怎么懂源码,最多会用,我的错,下次一定先动手尝试下,再下结论😭 😭 😭 😭

qq2729877005 关闭了讨论。 07月22日 14:03
需要 登录 后方可回复, 如果你还没有账号请 注册新账号