한 필드 또는 다른 필드의 존재 여부 확인 (XOR)


답변:


155

다음과 같이 수치 유효성 검사에 조건을 추가하면 코드가 작동합니다.

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

기능이 훌륭하게 작동합니다. 그러나 양식 페이지에 표시된 오류를 얻을 수 없습니다. 내 _form.slim에서 ´ = @ invoice.errors [: base] [0]`와 같은 작업을 수행하지 않는 한. 어떤 제안?
bir_ham

46

Rails 3+에서는 이것이 더 관용적이라고 생각합니다.

예 : user_name또는 중 하나가 있는지 확인하려면 email:

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

27
이것은 "둘"기준을 처리하지 않습니다
폴 Pettengill

11
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

3 개 이상의 값으로이 작업을 수행 할 수도 있습니다.

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

10

레일의 예 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

2
 validate :father_or_mother

# 아버지 성 또는 어머니 성은 필수입니다.

 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

위의 간단한 예를 시도하십시오.


1

이 질문에 대한 답을 아래에 넣었습니다. 이 예에서 :description:keywords필드는 어떤이되지 빈 중 하나

  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

1

: if 및 : unless와 함께 Proc 또는 Symbol을 사용하는 유효성 검사 는 유효성 검사가 발생하기 직전에 호출됩니다.

따라서 두 필드 중 하나가 다음과 같을 수 있습니다.

validates :charge,
  presence: true,
  if: ->(user){user.charge.present? || user.payment.present?}
validates :payment,
  presence: true,
  if: ->(user){user.payment.present? || user.charge.present?}

(예제 스 니펫) 코드에는 :if또는 :unless최신 항목이 있지만 문서에 선언 된대로 유효성 검사가 발생하기 직전에 호출되므로 조건이 일치하면 다른 검사가 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.