【问题标题】:Conditional allow_nil part of validation验证的条件 allow_nil 部分
【发布时间】:2013-11-08 20:39:46
【问题描述】:

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

目前我的解决方案通常是允许_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

should matchers 不能处理 procs 中的关联吗?

【问题讨论】:

    标签: ruby-on-rails validation activerecord


    【解决方案1】:

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

    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
    

    【讨论】:

      【解决方案2】:

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

      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 从轨道回购。然后,使用以下代码创建 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? }
      

      按这个顺序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多