I have a field that is serialized to YAML through the default AR behavior. It is currently in an Array of Hashes for examples:
[{'name' => 'hi', 'url' => 'bye'},
{'name' => 'hi', 'url' => 'bye'},
{'name' => 'hi', 'url' => 'bye'}]
Is there a way I can use some basic AR validations on some of these fields?
Yes, use the validates_each
method
serialize :urls
validates_each :urls do |record, attr, value|
# value is an array of hashes
# eg [{'name' => 'hi', 'url' => 'bye'}, ...]
problems = ''
if value
value.each{|name_url|
problems << "Name #{name_url['name']} is missing its url. " \
unless name_url['url']}
else
problems = 'Please supply at least one name and url'
end
record.errors.add(:urls, problems) unless problems.empty?
end
Added: You can't use the validations such as validates_length_of
since the validation method doesn't understand the format of your serialized field.
The validates_each
method is good since it enables you to write your own validation method. The method can then add an error to the record if appropriate.
Tip: You can also add an error to the :base
of record.errors rather than to the specific attribute. Sometimes this can help with the formatting of the error messages in your views.
Leaving this here in case it helps anyone in the future - I've written a gem to better handle validating serialized attributes. You can just put those validations in a block syntax, the ways you might expect to:
serialize :urls
validates_hash_keys :urls do
validates :name, presence: true
validates :url, presence: true
end
https://github.com/brycesenz/validates_serialized
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With