Пропустить проверку на нескольких полях

У меня есть модель 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. Как я имею отношение patientbelongs_to: doctor, Я могу использовать - hidden_field_tag :doctor_id, value: @doctor.idи сделайте проверку, как сказали ребята, unless: ->(patient){patient.doctor_id.present?}, PS, если кто-то использует devise, мы должны также пропустить разработку devid на email а также password, Мы можем добавить к модели, в моем случае Patient, что-то вроде этого:

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

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

5 ответов

Решение

Это кажется таким простым вопросом, но чем дольше я думаю об этом, тем больше возможных решений. Мне трудно сказать, какой из них самый сухой. Быстрое и грязное решение было бы добавить скрытое логическое поле xyz в форме доктора. Вам придется добавить этот атрибут в нижней части вашего контроллера, если вы используете Rails 4. С этим вы можете сделать что-то подобное в вашей модели:

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

Что мне нравится делать, это (в модели):

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

Хотя он делает то же самое, что и другие ответы, я нахожу это чище.

Вы можете сделать что-то подобное:

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

Я бы добавил к пациенту дополнительное поле, в котором указывалось бы, сам пациент зарегистрирован или нет.

Так, например, добавить поле source который может быть patient или же doctorили логическое поле self_registered что верно, если пациентка зарегистрировалась сама.

Ваша проверка станет

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

Использование временного поля работает только при создании пользователя, но при редактировании / обновлении пользователя на более позднем этапе произойдет сбой (поскольку в этот момент вы больше не будете знать, регистрировалась ли пациентка или нет, ---- можно предположить, это, но никогда не знаешь наверняка).

Я написал драгоценный камень, который выполняет этот вид "условной" проверки. Мой вывод заключается в том, что лучший способ выполнить условную валидацию состоит в том, чтобы контроллер решал, когда включать любые нестандартные правила валидации. Таким образом, если вы следуете как можно большему количеству практик RESTful, у вас должен быть другой контролер для врача, а не для подачи формы пациента. Или, если нет, то хоть какой-то способ сказать, верно? В любом случае, контроллер может затем направить модели на то, что делать проверки. Вот ссылка на жемчужину... надеюсь, она подходит и для вашей ситуации:

https://github.com/pdobb/conditional_validation

По сути, он предоставляет несколько методов-оболочек для виртуального атрибута, который вы настраиваете и который я называю "validation_accessor". Затем он предоставляет синтаксический сахар для того же рода вещи, которые другие предлагают в этой теме.

Другие вопросы по тегам