mirror of https://github.com/rails/rails
Change Numericaly validator to use round
f72f743
introduces truncate(scale) in the Numericality validator.
This behaviour conflicts with AR decimal type conversion,
which uses round(scale) instead.
Changes the Numericality validator in order to use
round(scale) for consistency.
This commit is contained in:
parent
2afc9059c9
commit
6657e3428b
|
@ -71,6 +71,8 @@ module ActiveModel
|
||||||
raw_value if raw_value.is_a?(Range)
|
raw_value if raw_value.is_a?(Range)
|
||||||
elsif raw_value.is_a?(Float)
|
elsif raw_value.is_a?(Float)
|
||||||
parse_float(raw_value, precision, scale)
|
parse_float(raw_value, precision, scale)
|
||||||
|
elsif raw_value.is_a?(BigDecimal)
|
||||||
|
round(raw_value, scale)
|
||||||
elsif raw_value.is_a?(Numeric)
|
elsif raw_value.is_a?(Numeric)
|
||||||
raw_value
|
raw_value
|
||||||
elsif is_integer?(raw_value)
|
elsif is_integer?(raw_value)
|
||||||
|
@ -81,7 +83,11 @@ module ActiveModel
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_float(raw_value, precision, scale)
|
def parse_float(raw_value, precision, scale)
|
||||||
(scale ? raw_value.truncate(scale) : raw_value).to_d(precision)
|
round(raw_value, scale).to_d(precision)
|
||||||
|
end
|
||||||
|
|
||||||
|
def round(raw_value, scale)
|
||||||
|
scale ? raw_value.round(scale) : raw_value
|
||||||
end
|
end
|
||||||
|
|
||||||
def is_number?(raw_value, precision, scale)
|
def is_number?(raw_value, precision, scale)
|
||||||
|
|
|
@ -103,6 +103,21 @@ class NumericalityValidationTest < ActiveRecord::TestCase
|
||||||
assert_not_predicate subject, :valid?
|
assert_not_predicate subject, :valid?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_virtual_attribute_with_precision_and_scale
|
||||||
|
model_class.attribute(:virtual_decimal_number, :decimal, precision: 4, scale: 2)
|
||||||
|
model_class.validates_numericality_of(
|
||||||
|
:virtual_decimal_number, less_than_or_equal_to: 99.99
|
||||||
|
)
|
||||||
|
|
||||||
|
subject = model_class.new(virtual_decimal_number: 99.994)
|
||||||
|
assert_equal 99.99.to_d(4), subject.virtual_decimal_number
|
||||||
|
assert_predicate subject, :valid?
|
||||||
|
|
||||||
|
subject = model_class.new(virtual_decimal_number: 99.999)
|
||||||
|
assert_equal 100.00.to_d(4), subject.virtual_decimal_number
|
||||||
|
assert_not_predicate subject, :valid?
|
||||||
|
end
|
||||||
|
|
||||||
def test_aliased_attribute
|
def test_aliased_attribute
|
||||||
model_class.validates_numericality_of(:new_bank_balance, greater_or_equal_than: 0)
|
model_class.validates_numericality_of(:new_bank_balance, greater_or_equal_than: 0)
|
||||||
|
|
||||||
|
|
|
@ -187,9 +187,17 @@ class ValidationsTest < ActiveRecord::TestCase
|
||||||
validates_numericality_of :wibble, greater_than_or_equal_to: BigDecimal("97.18")
|
validates_numericality_of :wibble, greater_than_or_equal_to: BigDecimal("97.18")
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_not_predicate klass.new(wibble: "97.179"), :valid?
|
["97.179", 97.179, BigDecimal("97.179")].each do |raw_value|
|
||||||
assert_not_predicate klass.new(wibble: 97.179), :valid?
|
subject = klass.new(wibble: raw_value)
|
||||||
assert_not_predicate klass.new(wibble: BigDecimal("97.179")), :valid?
|
assert_equal 97.18.to_d(4), subject.wibble
|
||||||
|
assert_predicate subject, :valid?
|
||||||
|
end
|
||||||
|
|
||||||
|
["97.174", 97.174, BigDecimal("97.174")].each do |raw_value|
|
||||||
|
subject = klass.new(wibble: raw_value)
|
||||||
|
assert_equal 97.17.to_d(4), subject.wibble
|
||||||
|
assert_not_predicate subject, :valid?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_numericality_validator_wont_be_affected_by_custom_getter
|
def test_numericality_validator_wont_be_affected_by_custom_getter
|
||||||
|
|
Loading…
Reference in New Issue