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

Rails - can not verify that at least one field is null

我有一个 class Prediction 其中 belongs_to 一个 currency 或一个 market.

  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

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

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

我认为多态关系更适合这样的关系

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

我相信这样的事情应该适用于你的情况:

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