Rails:仅在创建时进行验证,或在字段不为空时进行更新

时间:2014-06-18 07:54:32

标签: ruby-on-rails ruby rails-activerecord

当字段不为空时,如何限制Rails验证以仅检查创建OR?我正在为我正在处理的应用创建用户设置页面,问题是,当使用表单提供的参数进行更新时,设置只会在存在密码和密码确认时保存。我想这些密码字段在创建时无论如何都要验证,但仅在提供时才更新。

5 个答案:

答案 0 :(得分:40)

如果您想允许空白值,请使用:allow_blank并带有验证。

class Topic < ActiveRecord::Base
  validates :title, length: { is: 5 }, allow_blank: true
end

如果您只想在创建时进行验证,请使用带有验证的on

class Topic < ActiveRecord::Base
  validates :email, uniqueness: true, on: :create
end

覆盖你的情况:

class Topic
  validates :email, presence: true, if: :should_validate?

  def should_validate?
    new_record? || email.present?
  end
end

答案 1 :(得分:12)

事实证明这比我想象的要简单一些。我将表单输入名称从passwordpassword_confirmation更改为new_passwordnew_password_confirmation。我使用以下行在我的模型中为这些值添加了临时访问器:

attr_accessor :new_password, :new_password_confirmation

我实现了一个password_changed?方法,定义如下:

def password_changed?
    !new_password.blank?
end

最后,我将验证更改为:

validates :new_password, presence: true, confirmation: true, length: { in: 6..20 }, on: :create
validates :new_password, presence: true, confirmation: true, length: { in: 6..20 }, on: :update, if: :password_changed?
validates :new_password_confirmation, presence: true, on: :create
validates :new_password_confirmation, presence: true, on: :update, if: :password_changed?

我很肯定有一个更好的方法(这不是很干)但是现在,它有效。改进的答案仍然非常受欢迎。

答案 2 :(得分:7)

无需更改字段名称,就足以在代码中将:password_changed?替换为:password_digest_changed?

validates :password, presence: true, confirmation: true, length: { in: 6..20 }, on: :create
validates :password, presence: true, confirmation: true, length: { in: 6..20 }, on: :update, if: :password_digest_changed?
validates :password_confirmation, presence: true, on: :create
validates :password_confirmation, presence: true, on: :update, if: :password_digest_changed?

答案 3 :(得分:6)

请尝试

validates :<attributes>, if: Proc.new{|obj| obj.new_record? || !obj.<attribute>.blank? }

或添加自定义方法名称而不是属性名称。

答案 4 :(得分:0)

这有效

validates :password, presence: true, length: { in: 6..20 }, if: :password_digest_changed?

Bcrypt gem要求password和password_confirmation相同,因此您只需要担心其中之一即可。在更新和创建上,password_digest都会更改。这意味着在创建时调用验证,并且仅在用户更新密码时才在更新上调用验证。您应该在前端进行js验证,但是这一行代码将在更新和创建时保护数据库。我自己对此进行了测试。您可能对此使用自定义验证,但我自己没有尝试过。游戏后期,希望这对某人有帮助。