Comment valider la présence d'un champ ou d'un autre mais pas des deux et d'au moins un?
Comment valider la présence d'un champ ou d'un autre mais pas des deux et d'au moins un?
Réponses:
Votre code fonctionnera si vous ajoutez des conditions aux validations de numéricité comme ceci:
class Transaction < ActiveRecord::Base
validates_presence_of :date
validates_presence_of :name
validates_numericality_of :charge, allow_nil: true
validates_numericality_of :payment, allow_nil: true
validate :charge_xor_payment
private
def charge_xor_payment
unless charge.blank? ^ payment.blank?
errors.add(:base, "Specify a charge or a payment, not both")
end
end
end
Je pense que c'est plus idiomatique dans Rails 3+:
Exemple: pour valider que l'un des éléments user_name
ou email
est présent
validates :user_name, presence: true, unless: ->(user){user.email.present?}
validates :email, presence: true, unless: ->(user){user.user_name.present?}
class Transaction < ActiveRecord::Base
validates_presence_of :date
validates_presence_of :name
validates_numericality_of :charge, allow_nil: true
validates_numericality_of :payment, allow_nil: true
validate :charge_xor_payment
private
def charge_xor_payment
if [charge, payment].compact.count != 1
errors.add(:base, "Specify a charge or a payment, not both")
end
end
end
Vous pouvez même le faire avec 3 valeurs ou plus:
if [month_day, week_day, hour].compact.count != 1
Exemple de rails 3.
class Transaction < ActiveRecord::Base
validates_presence_of :date
validates_presence_of :name
validates_numericality_of :charge, :unless => proc{|obj| obj.charge.blank?}
validates_numericality_of :payment, :unless => proc{|obj| obj.payment.blank?}
validate :charge_xor_payment
private
def charge_xor_payment
if !(charge.blank? ^ payment.blank?)
errors[:base] << "Specify a charge or a payment, not both"
end
end
end
validate :father_or_mother
# Le nom du père ou le nom de la mère est obligatoire
def father_or_mother
if father_last_name == "Last Name" or father_last_name.blank?
errors.add(:father_last_name, "cant blank")
errors.add(:mother_last_name, "cant blank")
end
end
Essayez ci-dessus un exemple simple.
Je mets ma réponse à cette question ci-dessous. Dans cet exemple, :description
il :keywords
y a des champs dont l'un d'entre eux n'est pas vide:
validate :some_was_present
belongs_to :seo_customable, polymorphic: true
def some_was_present
desc = description.blank?
errors.add(desc ? :description : :keywords, t('errors.messages.blank')) if desc && keywords.blank?
end
La validation utilisant un Proc ou un Symbole avec: si et: sauf sera appelée juste avant que la validation ne se produise.
Donc, la présence d'un des deux champs peut être comme ceci:
validates :charge,
presence: true,
if: ->(user){user.charge.present? || user.payment.present?}
validates :payment,
presence: true,
if: ->(user){user.payment.present? || user.charge.present?}
Le code (exemple d'extrait de code) a :if
ou :unless
comme dernier élément, mais comme déclaré dans le document, il sera appelé juste avant la validation - donc une autre vérification fonctionnera après, si la condition correspond.