Пропустить проверку на нескольких полях
У меня есть модель 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?}
, 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". Затем он предоставляет синтаксический сахар для того же рода вещи, которые другие предлагают в этой теме.