The Ruby on Rails framework doesn't allow you to validate enums submitted through a form in any sane manner. Evidently, enums are meant to be used to maintain internal application state, and are not supposed to be user-facing. Well, in my case it doesn't matter too much, but I still want validations *just in case*.
Here is a widely-used enum:
class Language < ActiveRecord::Base self.abstract_class = true enum language: { arabic: 0, chinese: 1, english: 2, french: 3, german: 4, italian: 5, japanese: 6, russian: 7, spanish: 8, other: 9 } end
In my schema, the field using this enum is a text
array: t.text "audio_languages", default: []
, allowing multiple languages to be selected through the form.
In the form, the values are added as a list of check boxes:
In the controller, the values for that field come in as:
"audio_languages"=>["English", ""]
Notice the last array entry, ""
. That's just how it works I guess, nothing I've tried gets rid of that, so I have to handle it in the validation.
In the validation, a language needs to be chosen, and the chosen language has to be present in the language
enum:
def validate_audio_languages # Remove the empty string, which is an artifact of form submission of an array # field, during validation audio_languages.reject! { |l| l.empty? } if !audio_languages.any? errors.add(:audio_languages, "need to select a language") end # If any of the audio languages is invalid, add the error and break audio_languages.each do |al| valid = false Language.languages.each do |l, i| valid = true if (al.downcase == l.downcase) end if !valid errors.add(:audio_languages, "not a valid language selection") break end end end
I'm concerned about the length of the function more than anything. Surely there's an easier way to do this kind of simple validation, especially to validate whether or not a value is actually in the enum. Any help in dealing with this issue is much appreciated!