2015-05-14 144 views
1

我有一個類Prediction,其中belongs_to或者currencymarketRails - 無法驗證至少有一個字段爲空

belongs_to :market 
    belongs_to :currency 

    validate :market_xor_currency?, on: [:new, :create, :edit, :update] 

    def market_xor_currency? 
    if(self.market != nil && self.currency != nil) 
     false 
    end 
    true 
    end 

我以這種方式使用RSpec測試:

p1 = FactoryGirl.create(:prediction) 
p1.currency = FactoryGirl.create(:currency) 
expect{ p1.market = FactoryGirl.create(:market) }.to raise_error 

然而,測試失敗。我如何使Prediction屬於currencymarket

回答

2

我認爲多態關係更適合這種關係

class Market < ActiveRecord::Base 
    has_many :predictions, as: :predictable 
end 

class Currency < ActiveRecord::Base 
    has_many :predictions, as: :predictable 
end 

class Prediction < ActiveRecord::Base 
    belongs_to :predictable, polymorphic: true 
end 

這你不需要驗證任何東西,因爲根據定義,預測只能屬於其中之一

More about polymorphic relations

如果你仍然想你說的辦,那我覺得這個驗證方法應該工作

def market_xor_currency? 
    unless market.nil?^currency.nil? 
    errors.add(:base, 'whatever error you want') 
    end 
end 
+0

謝謝你告訴我關於多態關係。我改變了代碼,但現在我在其他一些測試中得到這個錯誤: 'PG :: UndefinedColumn:ERROR:列predictions.predictable_type不存在 LINE 1:... ns「WHERE」predictions「。」predictable_id「= $ 1 AND「預測... ^ :選擇」預測「。*從」預測「WHERE」預測「。」predictable_id「= $ 1 AND」預測「。」predictable_type「= $ 2 LIMIT 1' – octavian

+1

是設置它你需要2個字段,predictable_type和predictable_id,你需要創建一個遷移來添加這兩個字段,而不是market_id和currency_id –

+0

檢查我的答案中的鏈接,你會發現詳細信息 –

0

我相信這樣的事情應該工作你的情況:

class MyValidator < ActiveModel::Validator 
    def validate(record) 
    if(record.market != nil && record.currency != nil) 
     record.errors[:name] << 'market xor currency' 
    end 
    end 
end 

class SomeModel < ActiveRecord::Base 
    include ActiveModel::Validations 
    validates_with MyValidator 
end 
+0

你能解釋爲什麼這將有助於OP與他們的問題? –

+0

代碼創建一個驗證程序,用於檢查選定記錄是否具有關聯的市場或貨幣關聯,如果它們具有這兩個驗證失敗並給出錯誤消息(異或邏輯)。之後驗證者被分配給模型。 – MravAtomski

相關問題