根据参数或操作调整模型验证的最佳方法是什么?假设我正在进入系统领域,所以所需要的只是基本的联系信息。但后来我可能会为该用户输入一份新合同,此时我需要更详细的信息。因此,我只需要输入一个潜在客户就可能需要电话号码,但一旦他们签订合同,我可能需要他们的生日和备用电话号码。
我考虑使用状态机,但用户实际上可以同时签订两份合同,因此状态对这种情况并不起作用。
我还考虑过将额外信息存储在合同中,但由于用户可以拥有多个合同,因此需要与用户共同使用,这样才不会多余。
所以基本上在保存合同时,如果所述用户没有额外的字段,它会告诉我附加用户无效。
答案 0 :(得分:4)
您可以使用conditional validation例如:
validates_presence_of :phone, :if => Proc.new { |p| p.lead? }
答案 1 :(得分:3)
class Person
validates_presence_of :given_name, family_name
validates_presence_of :phone_number, :email_address, :if => :registered
with_options :if => :registered do |person|
# validations in this block are scoped to a registered user
person.validates_presence_of :dob
end
end
:if
选项可以:
您还可以访问以类似方式工作的:unless
选项。
您还可以封装逻辑以确定用户的当前状态,并使用它来确定您可以采取的验证步骤:
class Person
validates_presence_of :email_address, :if => ->(p) { p.state == :pending_confirmation }
# I actually prefer validations in this format
validate do # stricter validations when user is confirming registration
if confirming_membership && (given_name.blank? || family_name.blank?
errors.add(:base, 'A full name is required')
end
end
def state
# your logic could be anything, this is just an example
if self.confirmed_email
:registered
elsif confirming_membership
:pending_confirmation
else
:new_user
end
end
def confirming_membership
# some logic
end
end
答案 2 :(得分:1)
无论领导发布什么行动,你都可以这样做:
@object.save(validate: false)
然后,当他们需要输入合同时,请不要使用validate: false
选项以确保运行这些验证。
另外,如果您只想跳过某些验证,请参阅this post。