更新配置文件和密码

时间:2013-09-26 08:25:23

标签: ruby-on-rails validation ruby-on-rails-4

我不确定如何最好地解决这个问题 - 我需要在添加新记录时验证用户的密码,我还需要能够在更新passoword时进行验证。但是,如何让用户只更新其个人资料的一部分,并可能将密码留空。

在你建议allow_blank之前

注意我知道这个选项但这不合适,因为当用户因丢失/遗忘而需要更改密码时我不想允许用户有一个空密码。

3 个答案:

答案 0 :(得分:1)

您可以将if语句传递给验证:

`validates_presence_of:password,:if => :should_validate_password

您应该能够在此处传递条件以捕获用户是否正在更新其密码:

<强>模型

def should_validate_password?
  updating_password || new_record?
end

<强>控制器

@user.updating_password = true
@user.save

请点击此处了解详情:http://railscasts.com/episodes/41-conditional-validations

<强>更新

在你的情况下,我会在控制器中创建一个if语句,检测是否在params中传递了任何新密码。如果是这样,我会设置@user.updating_password = true,这将触发模型中的验证。如果没有,则@user.updating_password将为零,并且不会触发验证。

答案 1 :(得分:1)

完全自定义方式

通常,#password=#password_confirmation=只是虚拟设置者,true属性为#hashed_password或其他。所以,你可以这样做:

class User
  attr_accessor :password, :password_confirmation

  validate :validates_password
  validates_presence_of :hashed_password

  private

  def validates_password
    if password or password_confirmation
      if password != password_confirmation
        errors.add( :password, 'your message' )
      end
      # your others validations

      self.hashed_password = hash_password
    end
  end

  def hash_password
    # your hashing code
  end
end

创建提供密码的用户时,会设置虚拟属性passwordpassword_confirmation,因此if条件为真,并且会强制执行验证。

如果已设置密码且用户未更改密码(不提供密码的编辑表单),则不会强制执行验证,因为if password and password_confirmation

当密码已设置且用户更改密码时,passwordpassword_confirmation已设置,因此会触发验证。

如果您想重置密码,只需将操作hashed_password设置为nil即可。由于validates_presence_of :hashed_password,模型现在无效,用户必须提供新模型。

使用#has_secure_password

使用#has_secure_password,rails将处理大部分内容,尤其是:

  • 它创建虚拟atttributes
  • 仅在提供密码属性时才会触发确认匹配验证
  • 它会哈希密码

所以,您需要的只是添加自己的验证,只有在passwordpassword_confirmation出现时才会这样做。

class User
  has_secure_password
  validate :validates_password

  private

  def validates_password
    if password or password_confirmation
      unless <your_test>
        errors.add( :password, '<your error message>' )
      end
    end
  end
end

如前所述,只有在提供password和password_confirmation时才会触发此操作,只有当用户将其作为表单数据提交时才会触发(实际属性为password_digest)。

答案 2 :(得分:1)

validates :password, presence: true, if: lambda { |user| user.password_changed? }

by ActiveModel :: Dirty(默认情况下适用于所有型号)