Reputation: 11336
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
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
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