【问题标题】:Rails devise reset password fails if user record contains invalid data如果用户记录包含无效数据,Rails 设计重置密码失败
【发布时间】:2019-01-20 03:06:59
【问题描述】:

我有一个生产中的现有应用程序,我们在用户记录中添加了新的必填字段。结果,忘记密码功能失败。我相信故障发生在recoverable.rb中的以下方法

  # Update password saving the record and clearing token. Returns true if
  # the passwords are valid and the record was saved, false otherwise.
  def reset_password(new_password, new_password_confirmation)
    if new_password.present?
      self.password = new_password
      self.password_confirmation = new_password_confirmation
      save
    else
      errors.add(:password, :blank)
      false
    end
  end

新属性无法机械生成。只有用户自己会知道正确的值。有谁知道解决这个问题的方法吗?

到目前为止,我想出的唯一想法如下:

  • 使用 rake 脚本用我知道在现实生活中永远不会出现但会被模型验证规则接受的值填充新字段

  • 当用户登录时,检测用户记录是否包含无效数据并强制他们进行更新。在用户编辑表单中,我会使用一些 javascript 将虚假值更改为空白。

【问题讨论】:

    标签: ruby-on-rails devise passwords


    【解决方案1】:

    您可以使用自定义验证上下文来确保这些添加字段的验证仅在用户编辑其个人资料时运行,但在(例如)Devise 保存用户记录时跳过。

    在用户模型中,将on:-clause 添加到这些验证中

    validates_presence_of :recently_added_mandatory_field, on: :user_updates_profile
    

    并在适当的控制器操作中,在调用#valid? 或#save 时添加此验证上下文:

    # Existing code uses `@user.valid?` -> change to:
    if @user.valid?(:user_updates_profile)
      …
    
    # Existing code uses `@user.save` -> change to:
    if @user.save(context: :user_updates_profile)
      …
    

    有关验证上下文的完整说明,请参见此处:https://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validates

    【讨论】:

    • 就我而言,当用户自己更新他的个人资料时,我使用的方法是更新,即@user.update(user_params)。我看不到任何地方显示如何为更新方法指定自定义验证上下文。
    • 只需将@user.update(user_params) 替换为两个语句:@user.assign_attributes(user_params); @user.save(context: :user_updates_profile)
    • 感谢您的提示。
    猜你喜欢
    • 2014-07-20
    • 2019-02-02
    • 1970-01-01
    • 1970-01-01
    • 2019-12-16
    • 2016-02-22
    • 2019-12-03
    • 1970-01-01
    • 2013-02-05
    相关资源
    最近更新 更多