validates_presence_of至少有一个这样的关联

时间:2013-08-16 07:22:03

标签: ruby-on-rails

WithdrawalAccount条记录包含SepaAccountInternationalAccountPayPalAccountOtherAccount。至少应该是其中之一。不能超过一个。

class WithdrawalAccount < ActiveRecord::Base
  has_one :sepa_account
  has_one :international_account
  has_one :third_account
  has_one :fourth_account
end

更新了问题: 我怎样才能validate_presence_of其中任何一个同时只允许其中一个出现。

2 个答案:

答案 0 :(得分:3)

尝试:

class WithdrawalAccount < ActiveRecord::Base
  has_one :sepa_account
  has_one :international_account

  validates :sepa_account,          presence: true, if: ->(instance) { instance.international_account.blank? }
  validates :international_account, presence: true, if: ->(instance) { instance.sepa_account.blank? }
end

要验证其中任何一个,您应该更喜欢以下方法:

class WithdrawalAccount < ActiveRecord::Base

  validate :accounts_consistency

  private

  def accounts_consistency
    # XOR operator more information here http://en.wikipedia.org/wiki/Xor
    unless sepa_account.blank? ^ international_account.blank?
      errors.add(:base, "options consistency error")
    end
  end
end

要验证的属性超过2个:

由于XOR 不起作用且有两个以上的属性(a ^ b ^ c),我们可以使用循环检查属性:

def accounts_consistency
  attributes = [sepa_account, international_account, third_account, fourth_account]
  result = attributes.select do |attr|
    !attr.nil?
  end

  unless result.count == 1
    errors.add(:base, "options consistency error")
  end
end

答案 1 :(得分:1)

你可以这样做

validate :account_validation

private

def account_validation
  if !(sepa_account.blank? ^ international_account.blank?)
    errors.add_to_base("Specify an Account")
  end
end

这里有答案(Validate presence of one field or another (XOR)