当字段不为空时,如何限制Rails验证以仅检查创建OR?我正在为我正在处理的应用创建用户设置页面,问题是,当使用表单提供的参数进行更新时,设置只会在存在密码和密码确认时保存。我想这些密码字段在创建时无论如何都要验证,但仅在提供时才更新。
答案 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)
事实证明这比我想象的要简单一些。我将表单输入名称从password
和password_confirmation
更改为new_password
和new_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验证,但是这一行代码将在更新和创建时保护数据库。我自己对此进行了测试。您可能对此使用自定义验证,但我自己没有尝试过。游戏后期,希望这对某人有帮助。