I have a validates inclusion: in my model, but I think the default error message of “is not included in the list” is entirely unuseful.
How do I make it show the list of allowed options in the error message itself? (for example, "is not one of the allowed options (option 1, option 2, or option 3)"?
More concretely, what is the most elegant way to get the following tests to pass:
describe Person do
describe 'validation' do
describe 'highest_degree' do
# Note: Uses matchers from shoulda gem
it { should allow_value('High School'). for(:highest_degree) }
it { should allow_value('Associates'). for(:highest_degree) }
it { should allow_value('Bachelors'). for(:highest_degree) }
it { should allow_value('Masters'). for(:highest_degree) }
it { should allow_value('Doctorate'). for(:highest_degree) }
it { should_not allow_value('Elementary School'). for(:highest_degree).with_message('is not one of the allowed options (High School, Associates, Bachelors, Masters, or Doctorate)') }
it { should_not allow_value(nil). for(:highest_degree).with_message('is required') }
it { subject.valid?; subject.errors[:highest_degree].grep(/is not one of/).should be_empty }
end
end
end
, given the following model:
class Person
DegreeOptions = ['High School', 'Associates', 'Bachelors', 'Masters', 'Doctorate']
validates :highest_degree, inclusion: {in: DegreeOptions}, allow_blank: true, presence: true
end
?
This is what I have in my config/locales/en.yml currently:
en:
activerecord:
errors:
messages:
blank: "is required"
inclusion: "is not one of the allowed options (%{in})"
Here’s a custom Validator that automatically provides the
%{allowed_options}interpolation variable for use in your error messages:Include in your config/locales/en.yml:
You can use it like this:
Or with a range:
Or with a lambda/Proc:
Comments are welcome! Do you think something like this should be added to the Rails (ActiveModel) core?
Is there a better name for this validator?
restrict_to_options?restrict_to?