#1038 ✓resolved
Jordan Ritter

Floats with fractional values don't validate

Reported by Jordan Ritter | September 11th, 2009 @ 11:52 AM

Observe:

require 'rubygems'
require "dm-core"
require "dm-validations"

DataMapper::Logger.new(STDOUT, :debug)
DataMapper.setup(:default, "sqlite3::memory:")

class Foo
    include ::DataMapper::Resource
    property :id, Serial
    property :price, Float, :default => 0.51
end

::DataMapper.auto_migrate!

foo = Foo.new
puts foo.valid?
puts foo.errors.inspect unless foo.save

puts "price = #{foo.price}"
puts foo.valid?

Outputs:

 ~ (0.000131) SELECT sqlite_version(*)
 ~ (0.000096) DROP TABLE IF EXISTS "foos"
 ~ (0.000023) PRAGMA table_info("foos")
 ~ (0.000354) CREATE TABLE "foos" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "price" FLOAT DEFAULT 0.51)
false
#<DataMapper::Validate::ValidationErrors:0x12b310c @errors={:price=>["Price must be a number"]}, @resource=#<Foo @id=nil @price=0.51>>
price = 0.51
false
#<DataMapper::Validate::ValidationErrors:0x12b310c @errors={:price=>["Price must be a number"]}, @resource=#<Foo @id=nil @price=0.51>>

FWIW, I think I had similar issues with BigDecimal.

Comments and changes to this ticket

  • Jonathan Stott (namelessjon)

    Jonathan Stott (namelessjon) September 11th, 2009 @ 07:21 PM

    • State changed from “new” to “unconfirmed”
    • Title changed from “Floats with default values don't validate” to “Floats with fractional values don't validate”
  • Jonathan Stott (namelessjon)

    Jonathan Stott (namelessjon) September 11th, 2009 @ 07:34 PM

    • State changed from “unconfirmed” to “confirmed”

    The issue isn't actually the default, it's due to the fact that fractional values are being stored in the column. A default of 1 would work fine as is. The issue is in a couple of places.

    The first is dm-core, lib/dm-core/property.rb, lines 833--834. Here, a Float property is given a precision of 10 and a scale of nil.

    The second is dm-validations, lib/dm-validations/validators/numeric_validator.rb, lines 83--95. The validator which is assigned ends up being

    /\A[+-]?(?:\d{1,#{precision}}(?:\.0)?)\z/
    

    This validator (from line 85) only allows whole numbers. It should be:

    /\A[+-]?(?:\d+|\d*\.\d+)\z/
    

    from line 94, which allows any floating point number.

    For this to come about, either float properties need to have a precision of nil, too. This shouldn't cause problems I can see. Alternatively, the logic in the validation needs reworking.

  • Dan Kubb (dkubb)

    Dan Kubb (dkubb) September 15th, 2009 @ 04:56 PM

    • State changed from “confirmed” to “resolved”

    (from [8f552a5ded986292e8560905eb1f1224cad8c9b3]) Do not validate Float unless precision and scale are explicitly defined

    [#1038 state:resolved] http://github.com/datamapper/dm-more/commit/8f552a5ded986292e856090...

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

Referenced by

Pages