在几个字段上跳过验证

时间:2014-05-11 11:01:44

标签: ruby-on-rails validation raiseerror

我有模型patient。当patient尝试注册时,他会填写字段,例如:nameemailtelephone,此字段上有验证presence。另外我还有另一种形式,医生可以为自己添加患者,这个表格只有一个字段name

问题:我可以以某种方式跳过字段emailtelephone上的验证,但在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

当params中出现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?}。 如果有人使用设计,我们也应该在emailpassword上跳过设计要求的验证。我可以添加模型,在我的案例中Patient,类似这样:

def password_required?
  false if self.doctor_id.present?
end

def email_required?
  false if self.doctor_id.present?
end

5 个答案:

答案 0 :(得分:3)

我喜欢做的是(在模型中):

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

尽管它与其他答案一样,我发现它更清洁。

答案 1 :(得分:1)

这似乎是一个如此简单的问题,但我想的时间越长,就会出现更多可能的解决方案。我很难分辨哪一个是DRYest。快速而肮脏的解决方案是以医生的形式添加隐藏的布尔字段xyz。如果您使用Rails 4,则必须在控制器底部添加该属性。您可以在模型中执行以下操作:

validates :name,  presence: true
validates :email, presence: true, unless: ->(patient){patient.xyz.present?}

答案 2 :(得分:0)

你可以这样做:

 validates :name,  presence: true
 validates :email,  presence: true, unless: ->(patient){patient.name.present?}

答案 3 :(得分:0)

我会在患者身上添加一个额外的字段,这表明患者是否自行注册。

例如,添加一个字段source,可以是patientdoctor,也可以添加一个布尔字段self_registered,如果患者注册了自己,则为真。

您的验证将成为

validates :name, presence: true
validates :email, presence: true, if: -> (patient.is_self_registered?)

使用临时字段仅在创建用户时有效,但在稍后阶段编辑/更新用户将失败(因为那时您将不再知道患者是否自己注册----你可以假设它,但永远不知道。)

答案 4 :(得分:0)

我写了一个宝石来完成这种“条件”验证。我的结论是,完成条件验证的最佳方法是让控制器决定何时启用任何非标准验证规则。因此,如果您尽可能多地遵循RESTful实践,那么您应该为医生提供不同的控制器与患者表单提交。或者,如果没有,那么至少有一些方法可以告诉,对吗?在任何情况下,控制器都可以指导模型进行验证。这是宝石的链接...希望它也适合你的情况:

https://github.com/pdobb/conditional_validation

基本上,它提供了一些围绕您设置的虚拟属性的包装方法,我称之为“validation_accessor”。然后它为其他人在这个帖子中提出的相同类型的东西提供语法糖。