We have a PostgreSQL array string field basically like:
add_column :books, :tags, :string, array: true, default: []
How can I add a validation to verify that that tags
array has at least 1 string in it, and that the string is from an enum set of strings?
I see we have accept
on string values, like this:
class Person < ApplicationRecord
validates :terms_of_service, acceptance: { accept: 'yes' }
validates :eula, acceptance: { accept: ['TRUE', 'accepted'] }
end
But what about on array[string] fields? Is something like this my best option?
class Book < ApplicationRecord
# tags :string is an Array
validate :tags_has_one_from_set
enum tag: {
foo: 'foo',
bar: 'bar'
}
def tags_has_one_from_set
allowed_tags = Book.tags.values
if tags.length == 0
errors.add(:tags, "Must select at least one tag")
elsif !tags.all? { |t| allowed_tags.include?(t) }
errors.add(:tags, "Must select from approved tag list")
end
end
end
Is there any more "built-in" or best-practice sort of way of doing this in Rails?
You should be able to use the built in length
and inclusion
validators:
validates :tags,
length: { minimum: 1, message: "must have at least one tag" },
inclusion: { in: tags.values, message: "must be selected from: #{tags.values.join ", "}" }