条件allow_nil部分验证

时间:2013-11-07 20:22:17

标签: ruby-on-rails validation activerecord

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

现在我的解决方案通常是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 }

但这显然不起作用。

有没有办法更有效地做到这一点?我还发现了this here on SO,但这看起来非常相似,基本上对同一件事使用了两个单独的验证。

PS:不知何故,我的验证中的过程搞乱了我的应该匹配的问题。像

这样简单的东西
it { should_not allow_value(0).for(:user_id) }

在同一模型中现在给我

undefined method `fan_priced?' for nil:NilClass

shoulda匹配器不能处理procs中的关联吗?

2 个答案:

答案 0 :(得分: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并添加this code来自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? }
按顺序

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