rajive jain
2009-Jun-24 13:57 UTC
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
Colin Law
2009-Jun-24 16:50 UTC
Re: At my wits end ! Controlling passed in negative values from a form
2009/6/24 rajive jain <rajive.jain-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:> > 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 ??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
rajive jain
2009-Jun-24 18:49 UTC
Re: At my wits end ! Controlling passed in negative values from a form
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 ! :-) 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 On Jun 24, 12:50 pm, Colin Law <clan...-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:> 2009/6/24 rajive jain <rajive.j...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>: > > > > > > > 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 ?? > > 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