Rails Validation: Limit input to specific values - ruby-on-rails

I'm looking for "the Rails Way" to write a validation that limits acceptable input values to a predetermined list.
In my case, I want to only accept the values "-5", "-2", "+2", "+5", and nil. However, I think this is best as a general question: how do you predefine a list of acceptable entry values in a Rails model?
Thanks!

validates_inclusion_of should work. For example:
validates_inclusion_of :attr, :in => [-5, -2, 2, 5], :allow_nil => true

You want to use validates_inclusion_of with the :in and :allow_nil options.
validates_inclusion_of :field, :in => %w(-5 -2 2 5), :allow_nil => true
You'll probably also want to use in conjunction with validates_numericality_of

Rails 3+
The modern way to do this is the following:
validates :field, inclusion: { in: [ -5, -2, 2, 5 ], allow_blank: true, message: "not an allowable number." }

Related

Ruby ActiveRecord: validate format of an integer field

I'm trying to validate the format of a field in an ActiveRecord. I want this field to either be empty, or contain a sequence of digits only (it is containing an optional port number for a database connection). I'm currently trying this:
validates_format_of :port, with: /\A[0-9]*\Z/, message: 'Only numbers allowed'
but without luck. I've found that adding a required number by using for example {1, 6} sort of works, but makes the field mandatory.
Any advice?
Many thanks in advance,
Joseph.
If you're looking to validate so that only numbers are allowed, then you should be able to use this:
validates :port, :numericality => {:only_integer => true}
You may want to try to validate the numericality of the field, like so:
validates_numericality_of :port, :only_integer => true
:only_integer will ensure that the value entered for :port is an integer.
You can also just add allow_blank: true
You can use this syntax as well
validates numericality: :only_integer

In ActiveRecord, validate that an attribute is present but may be empty

I'm trying to set up my model in Rails 3.2.8 such that particular values must be present, but are allowed to be the empty string. Does anyone know how to do this?
The behavior I'm looking for looks like:
#foo.value = "this is a real value"
#foo.valid? # => true
#foo.value = nil
#foo.valid? # => false
#foo.value = ""
#foo.valid? # => true
If I use
validates :foo, :presence => true
then I get what I want for 1 and 2, but not 3. And, helpfully, :allow_blank => true is ignored when validating presence.
I also tried
validates :foo, :length => { :minimum => 0 }, :allow_nil => false
Same behavior: get what I want for 1 and 2, but not 3.
I suppose I could just mark the column as NOT NULL in the database, but then I have to deal with catching the exception; I'd really rather catch this at the validation stage.
Any ideas?
I would try something like this:
validates :foo, presence: true, unless: lambda { |f| f.foo === "" }

Duplicate flash error messages with multiple validations

I am currently validating my model using this code:
validates :price, :presence => true, :numericality => {:greater_than => 0}
This works fine, except that when I do not enter any value in this field, I get 2 errors - both "Price can't be blank" and "Price is not a number".
I can understand why this happens - clearly it is failing both tests. But i'm wondering if there is a way to ge the validation to stop after one test, since there is no point testing if the number is > 0 if there is no number at all?
Thanks!
Edit: For clarity, I don't want to allow the field to be blank, I just don't want the numericality test to run if it is blank, to avoid 2 error messages for what is really 1 error.
Not sure if it will work, but you can try:
validates :price, :presence => true, :numericality => {:greater_than => 0, :allow_blank => true }

Validates_length_of using within, but the field shouldn't be mandatory?

I am doing this:
validates_length_of :some_field, :within => 0..10
And a empty field returns an error, why is that?
How can I check to make sure it is between 0..10, but the field in the form isn't mandatory?
You're close:
validates_length_of :some_field, :within => 0..10, :allow_blank => true
You can change the zero minimum size, since it will only be triggered when there is some input.
See also the validation docs.
You can pass :allow_blank as an option to allow this:
validates_length_of :some_field, :within => 0..10, :allow_blank => true
try:
validates_length_of :some_field, :within => [0..10], :if => :some_field?
Maybe it's a nil value instead of an empty string that it gets validated against ?
irb(main):006:0> ''.length
=> 0
irb(main):007:0> nil.length
NoMethodError: You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.length
from (irb):7

Ruby on Rails - Validate a Cost

What is the best way to validate a cost/price input by a user, validation rules below:
Examples of formats allowed .23, .2, 1.23, 0.25, 5, 6.3 (maximum of two digits after decimal point)
Minimum value of 0.01
Maximum value of 9.99
Check the price and verify the format
#rails 3
validates :price, :format => { :with => /\A\d+(?:\.\d{0,2})?\z/ }, :numericality => {:greater_than => 0, :less_than => 10}
#rails 2
validates_numericality_of :price, :greater_than => 0, :less_than => 10
validates_format_of :price, :with => /\A\d+(?:\.\d{0,2})?\z/
For client side validations you can use a jQuery plugin like this one that allows you to define different valid formats for a given input.
For server side validations and according to this question/answer maybe you should use a decimal column for price in which you can define values for precision and scale, scale solves the two digits after decimal point restriction.
Then to validate the numericality, minimum and maximum value you can use the next validation method:
validates_numericality_of :price, :greater_than => 0, :less_than => 10
You can build custom validations.Lets say, for example the second case:
validate :price_has_to_be_greater_than_minimum
def price_has_to_be_greater_than_minimum
errors.add(:price, "price has to be greater than 0.01") if
!price.blank? and price > 0.01
end
More on this, in the Rails Guides, here.

Resources