Rails验证,知道哪个字段无效?

时间:2015-08-04 10:09:35

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

我有一个可行的模型。

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在test中的值field1无效。现在我想清除这个领域,只有这个。

如何找到无效的字段?像product.field1.valid?

这样的东西

3 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:4)

这样做很容易,但有关性能的一些事项需要牢记:

  1. 想要将所有产品加载到内存中,并迭代它们,
  2. 如果可能,您不应该尝试逐个更新它们。
  3. 这可能是一个可以接受的解决方案:

    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)
    

答案 2 :(得分:0)

您可以使用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