98 votes

Valider la présence d'un champ ou d'un autre (XOR)

Comment valider la présence d'un champ ou d'un autre mais pas les deux et au moins un?

158voto

semanticart Points 2773

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
      if !(charge.blank? ^ payment.blank?)
        errors.add(:base, "Specify a charge or a payment, not both")
      end
    end

end
 

48voto

jmanrubia Points 515

Je pense que c'est plus idiomatique dans Rails 3+:

Exemple: pour valider que l'un des user_name ou email soit présent:

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

11voto

Kieran Andrews Points 3002
 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:

 if [month_day, week_day, hour].compact.count =! 1
 

10voto

Seoman Points 162

Exemple pour les 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
 

2voto

chaitanya saraf Points 391
  validate :father_or_mother
 

# Le nom de famille du père ou le nom de famille 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 exemple simple.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X