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?
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