我有型号patient
。当patient
尝试注册时,他会填充字段,例如:name
、email
、telephone
,并且在这些字段上有验证presence
。此外,我还有另一个表单,医生可以在其中为自己添加患者,这个表单只有一个字段name
。
问题:我可以以某种方式跳过字段email
和telephone
的验证,而将验证保留在name
上吗?
目前,我有这样的行动:
def add_doctor_patient
@patient = @doctor.patients.new(patient_params)
if params[:patient][:name].present? and @patient.save(validate: false)
redirect_to doctor_patients_path(@doctor), notice: 'Added new patient.'
else
render action: 'new'
end
end
当参数中存在name
时,我跳过验证并保存患者,但当name
不存在时,它只会呈现new
动作,没有错误,simple_form不会用红色标记字段。也许有办法引起错误,或者只是另一种解决方案?
UPD
解决方案:遵循wintermeyer的答案。由于我有关系式patient
belongs_to: doctor
,我可以使用-hidden_field_tag :doctor_id, value: @doctor.id
,并像伙计们说的那样进行检查,unless: ->(patient){patient.doctor_id.present?}
。P.S如果有人使用设计,我们也应该跳过email
和password
上设计要求的验证。我们可以添加到模型中,在我的例子中是Patient
,类似这样的东西:
def password_required?
false if self.doctor_id.present?
end
def email_required?
false if self.doctor_id.present?
end
我喜欢做的是(在模型中(:
attr_accessor :skip_validations
validates :name, presence: :true
validates :email, presence: :true, unless: :skip_validations
validates :telephone, presence: :true, unless: :skip_validations
然后在控制器中:
patient = Patient.new(patient_params)
patient.skip_validations = true
尽管它和其他答案一样,但我觉得它更干净。
这似乎是一个简单的问题,但我想的时间越长,可能的解决方案就越多。我很难判断哪一个是DRYest。快速而肮脏的解决方案是在医生的表单中添加一个隐藏的布尔字段xyz
。如果你使用Rails 4,你必须在控制器的底部添加这个属性。有了它,你可以在你的模型中做这样的事情:
validates :name, presence: true
validates :email, presence: true, unless: ->(patient){patient.xyz.present?}
您可以这样做:
validates :name, presence: true
validates :email, presence: true, unless: ->(patient){patient.name.present?}
我会在patient中添加一个额外的字段,指示患者是否自行注册。
因此,例如,添加一个字段source
,它可以是patient
或doctor
,或者添加一个布尔字段self_registered
,如果患者自己注册了,它是真的。
然后您的验证将变成
validates :name, presence: true
validates :email, presence: true, if: -> (patient.is_self_registered?)
使用临时字段只在创建用户时有效,但在后期编辑/更新用户时会失败(因为那时你将不再知道患者是否注册了——你可以假设,但永远无法确定(。
我写了一个gem来完成这种"条件"验证。我的结论是,实现条件验证的最佳方法是让控制器决定何时启用任何非标准验证规则。因此,如果你尽可能多地遵循RESTful实践,那么你应该为医生和患者的表单提交提供一个不同的控制器。或者,如果不是,那么至少有一些方法可以告诉你,对吧?在任何情况下,控制器都可以指导模型进行验证。这是宝石的链接。。。希望它也适合你的情况:
https://github.com/pdobb/conditional_validation
基本上,它围绕您设置的虚拟属性提供了一些包装方法,我称之为"validation_accessor"。然后,它为其他人在这条线索中提出的相同类型的东西提供了语法糖。