Reputation: 2296
i had a model which works fine.
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
some of my entries in the database are invalid. these are older entries. i want to run a seed which find these invalid entries
Product.all.each do |product|
next if product.valid?
#
end
i want to clear the attributes which are invalid. let me say, Product 1 has the value test
in field1
which is invalid. now i want to clear this field, and only this.
how do i find the fields which are invalid? something like product.field1.valid?
Upvotes: 9
Views: 7182
Reputation: 44370
The Rails api allows you to get the error message by the key with the ActiveModel::Errors#get
method:
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
Upvotes: 8
Reputation: 5112
you can check and validate the model and its attribute using valid? and can also check for 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
Upvotes: 0
Reputation: 12412
Doing it is easy, but there are a couple of things to keep in mind about performance:
This might be an acceptable solution:
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)
Upvotes: 4