Ruby on rails Rails-无法验证至少一个字段是否为空

Ruby on rails Rails-无法验证至少一个字段是否为空,ruby-on-rails,rspec,Ruby On Rails,Rspec,我有一个类Prediction,它属于货币或市场 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

我有一个类
Prediction
,它属于
货币或
市场

  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

然而,测试失败了。如何使
预测
属于
货币
市场

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


我认为多态关系更适合这种关系

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

我相信在你的情况下,这样的事情应该是可行的:

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
class MyValidatorrecord.errors[:name]我按指示执行了,但测试仍然失败。您能解释一下为什么这有助于OP解决问题吗?代码创建了一个验证器,用于检查所选记录是否具有关联的市场或货币关联,以及是否同时具有这两个验证失败和给定的错误消息(xor逻辑)。然后验证器被分配给模型。谢谢你告诉我多态关系。我更改了代码,但现在在一些其他测试中出现此错误:
PG::UndefinedColumn:error:column predictions.predictable\u type不存在第1行:…ns“其中”predictions“。“predictable\u id”=$1和“predictio…”选择“预测”。*从“预测”中选择“预测”。“可预测的\u id”=$1和“预测”。“可预测的\u类型”=$2限制1
yea要设置它,您需要两个字段,可预测的\u类型和可预测的\u id,您需要创建一个迁移来添加这两个字段,当你有一个预测对象时,当你说
@prediction时,你会找到详细信息和提示,而不是market\u id和currency\u id检查我答案中的链接。可预测的
它会在另一边返回对象,如果是market,它会返回market对象,如果是currency,它会返回currency对象
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