validation order firing

If you have:

validates_presence_of validates_uniqueness_of …

validates_each

What fires in what order?

If you have:

validates_presence_of validates_uniqueness_of …

validates_each

What fires in what order?

the way you order them in your model file. so validates_presence_of goes first,

uniqueness next then validates_each.

Ok, well the value in the validates_each is giving me nil, not sure why. Error is:

The error occurred while evaluating nil.>=):

validates_presence_of :code validates_uniqueness_of :code validates_presence_of :valid_from_date, :expiry_date validates_each :expiry_date do |record, attribute, value| record.errors.add(:expiry_date, ‘must be after or the same as valid from date’) unless value >= record.valid_from_date end

Ok, well the value in the validates_each is giving me nil, not sure why. Error is:

The error occurred while evaluating nil.>=):

validates_presence_of :code validates_uniqueness_of :code validates_presence_of :valid_from_date, :expiry_date

validates_each :expiry_date do |record, attribute, value| record.errors.add(:expiry_date, ‘must be after or the same as valid from date’) unless value >= record.valid_from_date end

the error says that value is nil so check first if it’s nil or not.

validates_each :expiry_date do |record, attribute, value|

record.errors.add(:expiry_date, ‘must be after or the same as valid from date’) if value && !(value >= record.valid_from_date) end

But is the validates_presence_of supposed to catch that first?

But is the validates_presence_of supposed to catch that first?

ah ok, now i see what you mean.

validations don’t work that way. all validations are run even when the previous

validations fail. that’s why you need to add :if and :except arguments so that

some validations are run only when some conditions are met.

OK, cool. Thanks.

Really? I'm not 100% sure that's right - although happy to be corrected.

I've not looked at the source, but I was under the impression the validations were added to a hash that was iterated when "valid?" is called, and a hash returns its elements in no guaranteed order...

I tend to do stuff like:

  validates_presence_of :foo   validates_uniqueness_of :foo, :if => :foo   validates_length_of :foo, :maximum => 255, :if => :foo

It's a very annoy feature of websites that tell you one error at a time:

"secret phrase cannot be blank" so you enter a phrase... "secret phrase must be longer than 6 characters" so you frown and make it longer "secret phrase can only contain alpha-numeric characters" so you growl and remove the punctuation and tweak the phrase "secret phrase must be no longer than 20 characters" you shop elsewhere..

If you have:

validates_presence_of

validates_uniqueness_of

validates_each

What fires in what order?

the way you order them in your model file. so validates_presence_of goes

first,

uniqueness next then validates_each.

Really? I’m not 100% sure that’s right - although happy to be corrected.

I’ve not looked at the source, but I was under the impression the

validations were added to a hash that was iterated when “valid?” is

called, and a hash returns its elements in no guaranteed order…

i’m not sure with rails 3, but i’m pretty sure with rails 2.x as i remember

adding comments in the models reminding coders to refrain from changing

the order of validations. since changing the validation orders changes the

order of the errors shown in the view.

but now that you mention it, maybe the order of when validations are run

is different with the order of errors shown.

The errors are stored in a hash (or at least used to be) so ordering isn't guaranteed on ruby 1.8

Fred