2013-08-16 33 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

相關問題