Validate presence of one field or another (XOR)
Your code will work if you add conditionals to the numericality validations like so:
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
return if charge.blank? ^ payment.blank?
errors.add(:base, 'Specify a charge or a payment, not both')
end
end
I think this is more idiomatic in Rails:
e.g: For validating that one of user_name
or email
is present:
validates :user_name, presence: true, unless: ->(user) { user.email.present? }
validates :email, presence: true, unless: ->(user) { user.user_name.present? }