Martin
Martin

Reputation: 11336

validates_presence_of at least one of these associations

A WithdrawalAccount record contains either a SepaAccount, InternationalAccount, PayPalAccount or OtherAccount. Should be at least one of these. Can not be more than one.

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

Updated Question: How can I validate_presence_of either one of them while allowing only one of them present.

Upvotes: 0

Views: 298

Answers (2)

Pierre-Louis Gottfrois
Pierre-Louis Gottfrois

Reputation: 17631

Try:

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

To validate either one you should prefer the following method:

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

With more than 2 attributes to validate:

Since the XOR will not work with more than 2 attributes (a ^ b ^ c) we could check the attributes using a loop:

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

Upvotes: 3

Charizard_
Charizard_

Reputation: 1245

You can do like this

validate :account_validation

private

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

There is answer here(Validate presence of one field or another (XOR))

Upvotes: 1

Related Questions