2013-08-16 29 views
0

A WithdrawalAccount记录包含SepaAccount,InternationalAccount,PayPalAccountOtherAccount。至少应该是其中之一。不能超过一个。validates_presence_of这些关联中的至少一个

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

更新问题: 我如何validate_presence_of它们中的一个,而只允许其中的一个存在。

回答

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将不工作与超过2个属性(a^b^c)我们可以ch埃克使用循环属性:

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 
+0

感谢。你将如何验证只有一个可以存在? 'sepa_account'或'international_account',但只有一个? – Martin

+0

当有4个属性来执行XOR时,这似乎有缺陷。例如:'nil^true^true^true'返回'true'。如果有人同时推送3种类型的帐户,看起来像这种XOR条件将会使他们一切顺利。 – Martin

+0

这是一个很好的问题。我会仔细研究它,看看我能想出什么 –

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)

+0

谢谢,请参阅更新的答案。如何在这种情况下管理4个值,同时让它更易于阅读? – Martin

相关问题