Rails - 无法验证至少有一个字段为空

时间:2015-05-14 15:21:52

标签: ruby-on-rails rspec

我有一个Predictionbelongs_to currencymarket

  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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

为了进行自定义方法验证,如果无效,则需要添加错误:

http://guides.rubyonrails.org/active_record_validations.html#custom-methods

答案 2 :(得分: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