106

I have a field that I would like to validate. I want the field to be able to be left blank, but if a user is entering data I want it to be in a certain format. Currently I am using the below validations in the model, but this doesn't allow the user to leave it blank:

validates_length_of :foo, :maximum => 5
validates_length_of :foo, :minimum => 5

How do I write this to accomplish my goal?

Promise Preston
  • 24,334
  • 12
  • 145
  • 143
bgadoci
  • 6,363
  • 17
  • 64
  • 91

9 Answers9

156

You can also use this format:

validates :foo, length: {minimum: 5, maximum: 5}, allow_blank: true

Or since your min and max are the same, the following will also work:

validates :foo, length: {is: 5}, allow_blank: true
quainjn
  • 2,089
  • 1
  • 14
  • 6
151

I think it might need something like:

validates_length_of :foo, minimum: 5, maximum: 5, allow_blank: true

More examples: ActiveRecord::Validations::ClassMethods

Kieran Andrews
  • 5,845
  • 2
  • 33
  • 57
DigitalRoss
  • 143,651
  • 25
  • 248
  • 329
17

Or even more concise (with the new hash syntax), from the validates documentation:

validates :foo, length: 5..5, allow_blank: true

The upper limit should probably represent somehting more meaningful like "in: 5..20", but just answering the question to the letter.

Fellow Stranger
  • 32,129
  • 35
  • 168
  • 232
  • In don't think `in` will work with strings, seems to be numbers only – ecoologic Jun 09 '15 at 02:42
  • 1
    This should work instead `validates :foo, length: 2..5, allow_blank: true` but ` length: { is: 5}` would do in the OP's case – PhilT Apr 05 '16 at 15:07
13

From the validates_length_of documentation:

validates_length_of :phone, :in => 7..32, :allow_blank => true

:allow_blank - Attribute may be blank; skip validation.

Gareth
  • 133,157
  • 36
  • 148
  • 157
3

every validates_* accepts :if or :unless options

validates_length_of :foo, :maximum => 5, :if => :validate_foo_condition

where validate_foo_condition is method that returns true or false

you can also pass a Proc object:

validates_length_of :foo, :maximum => 5, :unless => Proc.new {|object| object.foo.blank?}
keymone
  • 8,006
  • 1
  • 28
  • 33
2
validates_length_of :reason, minimum: 3, maximum: 30

rspec for the same is

it { should validate_length_of(:reason).is_at_least(3).is_at_most(30) }
shiva kumar
  • 11,294
  • 4
  • 23
  • 28
2

How about that: validates_length_of :foo, is: 3, allow_blank: true

shem
  • 4,686
  • 2
  • 32
  • 43
-1

Add in your model:

validates :color, length: { is: 7 }

color is a string:

t.string :color, null: false, default: '#0093FF', limit: 7
-4

In your model e.g.

def validate
  errors.add_to_base 'error message' unless self.foo.length == 5 or self.foo.blanc?
end
codevoice
  • 474
  • 3
  • 6