【问题标题】:Rails validation, knowing which field is invalid?Rails 验证,知道哪个字段无效?
【发布时间】:2015-08-04 10:09:35
【问题描述】:

我有一个工作正常的模型。

class Product < ActiveRecord::Base
  validates_format_of :field1, with: /\A[0-9\+\-\/\s]+\Z/, allow_nil: true
  validates_format_of :field2, with: /\A[0-9\+\-\/\s]+\Z/, allow_nil: true
end

我在数据库中的某些条目无效。这些是较旧的条目。 我想运行一个种子来找到这些无效条目

Product.all.each do |product|
  next if product.valid?
  # 
end

我想清除无效的属性。让我说,产品 1 在 field1 中的值 test 无效。现在我想清除这个字段,只有这个。

我如何找到无效的字段?类似product.field1.valid?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 validation


    【解决方案1】:

    Rails api 允许您使用ActiveModel::Errors#get 方法通过键获取错误消息:

    Product.all.each do |product|
      product.valid? # => run validation callbacks
    
      product.errors.messages          # => {:field1=>["cannot be nil"]}
      product.errors.get(:field1)      # => ["cannot be nil"]
      product.errors.get(:field2)      # => nil
    
      # `include?` and `has_key?` works too(it's aliases)
      product.errors.messages          # => {:field1=>["cannot be nil"]}
      product.errors.include?(:field1) # => true
      product.errors.include?(:field2) # => false
    
      # 
    end
    

    【讨论】:

    • 小心Product.all.each。如果您有数千种产品,那将削弱您的数据库/进程/服务器等
    • OP 问题与性能无关。他对数以千计的产品只字不提,全是检查错误信息,请不要调换轮子。
    • 我没有换轮子。 SO 不是为了获得分数,而是为了提供有用的答案。我发布该评论是因为根据我的经验Model.all.each 很危险。
    • 啊太棒了。多谢。那真的是我要找的。 @tomave 你是对的,但数据库中的条目少于 100 个。并且每次运行一次。
    【解决方案2】:

    这样做很容易,但在性能方面有几点需要牢记:

    1. 只想将所有产品加载到内存中并对其进行迭代,
    2. 如果可能,您不应该尝试一一更新。

    这可能是一个可接受的解决方案:

    invalid_ids = []
    
    Product.find_each(batch_size: 200) do |product|
      if !product.valid?
        if product.errors.include?(:field_1)
          invalid_ids << product.id
        end
      end
    end
    
    Product.where(id: invalid_ids).update_all(field_1: nil)
    

    【讨论】:

    • 这也是一个很好的解决方案,但我真的必须一次更新,因为我必须清除 field1field2 或/和 field3 所以我将另一个标记为答案
    【解决方案3】:

    您可以使用valid?检查和验证模型及其属性,也可以检查errors

    Product.all.each do |product|
     if  !product.valid? and !product.errors[field1].blank?
        ##do something if product is not valid and there is error in attribute that you may want to check
     end
    end
    

    【讨论】:

      猜你喜欢
      • 2015-02-03
      • 2022-11-03
      • 2018-02-15
      • 1970-01-01
      • 1970-01-01
      • 2011-05-27
      • 1970-01-01
      • 2016-11-13
      • 1970-01-01
      相关资源
      最近更新 更多