0

编写一个浮动属性验证时,我偶然发现了一个我总是想验证数值的情况,但在某些情况下只允许使用。

现在我的解决方案通常是allow_nil,但随后编写一个单独的存在验证。

validates :price, numericality: { greater_than: 0 }, allow_nil: true
validates :price, presence: true,
  if: Proc.new { |v| v.voting.fan_priced? }

这有效,但似乎并不干净。理想情况下,我想要这样的东西(一种伪代码):

validates :price, numericality: { greater_than: 0 },
  allow_nil: Proc.new { |v| v.voting.fan_priced? ? false : true }

但这显然行不通。

有没有办法更有效地做到这一点?我也在SO 上找到了这个,但这看起来很相似,本质上对同一件事使用了两个单独的验证。

PS:不知何故,我验证中的过程弄乱了我的应该匹配器。简单的东西,比如

it { should_not allow_value(0).for(:user_id) }

在同一个模型现在给了我

undefined method `fan_priced?' for nil:NilClass

应该匹配器不能处理过程中的关联吗?

4

2 回答 2

0

我想我找到了一种使用新缺勤验证器效果更好的方法:

validates :price, numericality: { greater_than: 0 }, if: 'voting.fan_priced?'
validates :price, absence: true, unless: 'voting.fan_priced?'

这样,我仍然有两个价格验证,但通过相反的 if 和 unless 声明它们处理相同的上下文更明显。

如果有人想使用缺席验证器,它仅在 rails 4 中可用。但是,如果您在 rails 3 项目中需要它,您可以简单地创建 lib/validators/absence_validator.rb 并从 rails repo添加此代码。然后,使用以下代码创建 config/initializers/core_extensions.rb 以使此自定义验证器在每个模型中都可用(否则您可能会遇到规格问题)

# Make custom validators available in each model
module ActiveModel::Validations
  Dir[Rails.root.join("lib/validators/**/*.rb")].each {|f| require f}
end

也许它可以帮助某人!

PS:哦,我通过做修复了那个奇怪的应该匹配器错误

if: Proc.new { |v| v.voting.present? and v.voting.fan_priced? }

以该顺序。

于 2013-11-07T22:45:53.887 回答
0

也许您可以使用自定义验证器:

validates :price, numericality: { greater_than: 0 }, allow_nil: true
validate :price_presence

def price_presence
  errors.add(:price,'Price cannot be blank.') if self.voting.fan_priced? and self.price.blank?
end
于 2013-11-08T02:04:07.613 回答