At my wits end ! Controlling passed in negative values from a form

Hi,

I am trying to validate a numeric value passed in from a form, which
is saved in a MySQL db as decimal(9,2)

Now problem is I need to ensure people don't enter a form value like -.
003. In my validations, I have a validates_numericality_of check being
done. Furthermore, in validate method, I have a check using an if
statement such as :

((an_object[n].nil? or an_object[n] < 0) and !an_object[n].blank?)

While testing, Rails validation can catch -0.003. However, it just
does not catch -.003 (without leading zero). In fact, in case of -.
003, the value gets saved as 0; if form value is -.008 let's say, it
gets saved as .01 in db (gets rounded off). Anything like -1.23 works
ok - meaning it is trapped as error.

I have a before_validation method which assigns 0 to undefined values
like so:
self.xxx = 0 unless self.xxx
(where xxx is name of attribute)

I have tried checking for a minus sign in before_validation & validate
method using xxx.to_s.include?("-"). I have also tried
using :greater_than and :minimum options in the
validates_numericality_of call. I also tried validates_inclusion_of,
giving a range from 0..9999999.99.

Nothing seems to work.

Would appreciate any insight into this ! ? What am I missing ??

Thank you

I am guessing a bit here but I assume what is happening here is that
the -.003 is being rounded to 0 because you have specified decimal
9,2. Then the validation is run, but as the value is now zero, which
is not negative, then the validation passes. Using before_validation
does not help as this is probably after the rounding.
I have little doubt that there is a better way but it you could do
this check in the controller before it is rounded.

Colin

Dear Colin

Thank you for your insight... indeed you are right the conversion is
happening before the validation - hence I thought before_validation
would catch it.

Anyways, I did move the checking to the controller and found something
interesting.

In the controller, the rounding takes place at the time of the model's
create call e.g. @person = Person.new(params[:person]) or when saving.
This I found by looking at the screen log and noting the attribute
value in the params hash vs the db table's insert call on the model.
Hence one needs to check this at earlier stage in the controller when
the raw params values come in via the post request.

Furthermore, at this stage, prior to @person = Person.new.....
definition, one has to be sure one has checked params is not nil,
which is the simple if statement like:

if request.post? and params[:person]

So, yes it worked finally - thank you indeed so much for your
insight ! :slight_smile:

I am certain there has to be a better way to do this no ... since it
opens up an entire bunch of 'check validation' fears for me in the
controller at the params level.

Thanks Colin and best regards