1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Merge pull request #41019 from intrip/40902-fix-numericality-validator

Use round(scale) in  ActiveModel NumericalityValidator
This commit is contained in:
Ryuta Kamizono 2021-01-14 17:14:31 +09:00 committed by GitHub
commit 63835772bb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 4 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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