在Rails中执行update_attributes时,如何仅验证特定字段?

时间:2011-11-28 21:09:07

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

我有User模型,其中有以下验证

validates :username, :presence => true, :uniqueness => true
validates :email, :presence => true, :uniqueness => true
validates :password, :confirmation => true
validates_presence_of :password, :on => :create

validates_presence_of :bnet_username, :on => :update
validates_presence_of :bnet_code, :on => :update

bnet_usernamebnet_code仅用于更新的原因是因为我在添加这些字段时已经有了现有用户而且他们不在注册表单中,因此我只需要用户设置他们一旦在网站上注册就会。

但是有一个问题,那就是没有设置bnet_usernamebnet_code的用户尝试重置密码。在这种情况下,PasswordResetController将尝试更新其属性,但验证将失败。

if @user.update_attributes(params[:user])
  redirect_to root_url, :notice => "Password has been reset! You can now log in."
...

问题是,我需要在用户尝试重置密码时验证密码,但我不想在他刚刚更新个人资料时验证密码。

我也无法在密码重置时一起跳过验证,因为我需要验证密码本身。

是否有任何简单的解决方案可以说明我需要运行哪些验证?或者我接近这个完全错误了?

编辑:基本上有一种情况会导致问题。尚未设置bnet_usernamebnet_code的现有用户,但他想更改密码。

由于密码更改是更新操作,因此会触发bnet_usernamebnet_password的验证。但是我需要将它们设置为仅更新,因为我希望用户在编辑其配置文件时设置它们。

当用户注册时,它不是必填字段,但是当他们尝试更新个人资料信息时,他们必须设置它。

2 个答案:

答案 0 :(得分:1)

你尝试过这样的事吗?

validates_presence_of :bnet_username, :on => :update, 
  :if => Proc.new { |user| !user.bnet_username.blank? }
validates_presence_of :bnet_code, :on => :update,
  :if => Proc.new { |user| !user.bnet_code.blank? }  

答案 1 :(得分:0)

您可以将:if:unless参数传递给验证,您可以使用这些验证来确定何时验证该特定字段。

示例:

:validate_presence_of :email, :unless => Proc.new { |user| user.signup_step <= 2 })