Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

validates_length_of, :is does not work for numbers

#843

validates_length_of does not work correctly - it compares the storage size instead of the number of characters.

This is because: irb(main):012:0> "123456".size => 6 irb(main):013:0> 123456.size => 8

A link to someone who found it already: http://theocacao.com/document.pa...

Reported by Stephen Brown · August 15th, 2008 @ 10:04 PM

State: wontfix
Milestone: 2.x
Assigned to: Frederick Cheung Frederick Cheung
Importance: none

Activity

  1. Ryan Bigg
    Ryan Bigg

    I can verify that this also doesn't work for me due to the fact it calls #size on a number.

    August 16th, 2008 @ 01:34 AM

  2. Philip Hallstrom
    Philip Hallstrom

    Looks like you could fix this by patching lines 539 and 556 of activerecord/lib/active_record/validations.rb to convert 'value' to a String if it's any of the various number types. But that might break apps that expect validates_length_of on a number to test byte size (weird, but maybe they exist).

    Just before the line that reads:

    value = value.split(//) if value.kind_of?(String)

    add:

    value = value.to_s if value.kind_of?(Integer)

    You'd want to catch Floats and BigNum and all the others too though.

    August 16th, 2008 @ 04:59 AM

  3. Jose Fernandez
    Jose Fernandez

    Created a patch for this issue. Modified the validates_length_of method in active_models/validations.rb so that all Numeric values get casted to a string before calling #size method on them. You can override this behavior (and go back to the old logic) by setting the new :byte_size option to true (false by default). Then the validation will check for the byte size of the Fixnum or Bignum value.

    Created a set of tests that fully test this new feature too, all previous tests + the new ones pass.

    August 26th, 2008 @ 10:03 PM

  4. Frederick Cheung
    Frederick Cheung

    seems to me that it's pure luck that integers happen to have a size method (thank you duck typing).

    Isn't this what the :greater_than etc... option of validates_numericality_of or validates_inclusion_of :foo, :in =>1000..10000 are for ?

    August 27th, 2008 @ 03:48 PM

  5. Stephen Brown
    Stephen Brown

    I was attempting to use it for checking the length of an account number and sort code. I guess they could both be strings, but the bug is there regardless of my situation - a user would expect validates_length_of for a number to give size, not bytesize

    August 27th, 2008 @ 03:55 PM

  6. Jose Fernandez
    Jose Fernandez

    The first patch had reduntant Float check at line 549 that slipped in, updated the patch to remove it.

    August 27th, 2008 @ 04:02 PM

  7. Jose Fernandez
  8. Philip Hallstrom
    Philip Hallstrom

    The problem with :greater_than or inclusion is that it doesn't work for zip codes (which I think is what the original post linked to as a problem).

    If you're storing zip codes as integers, then you can't say :greater_than => 10000 an :less_than <= 99999 because 00501 is a valid zip code, but as an integer wouldn't fall in that range.

    So in the zip code scenario you really do have to check the number of digits.

    There are probably other situations as well...

    August 27th, 2008 @ 04:27 PM

  9. Jose Fernandez
    Jose Fernandez

    The old logic would also crash if you assign a float to the attribute being validated (manually of course because this would be impossible from within an html form), because it would call #size on the Float instance and crash.

    August 27th, 2008 @ 04:31 PM

  10. Frederick Cheung
    Frederick Cheung

    On 27 Aug 2008, at 16:27, Lighthouse wrote:

    August 27th, 2008 @ 05:00 PM

  11. Frederick Cheung
    Frederick Cheung

    D'oh screwed up the mail to reply thing. What I was saying is that if your data is something like 00500 then it shouldn't be a number, it should be a string. By the time it gets to a validation it will be typecast to 500 and so any sort of validates_length that checks it's 5 digits long will fail

    August 27th, 2008 @ 05:10 PM

  12. Pratik
    Pratik
    • Tag changed from 2.1, bug to 2.1, activerecord, bug, patch, validations
    • Assigned user set to Frederick Cheung
    • State changed from new to wontfix

    Agree with what Fred said. You should be using strings.

    December 22nd, 2008 @ 12:22 AM