diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2018-08-28 17:23:48 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-28 17:23:48 +0900 |
commit | 37075aa7f5c2c779a981debd21aa8c468cce4d72 (patch) | |
tree | d84791f45de533765855ae6b556e3c1e6ea48ca6 | |
parent | 1353610ff2ab4d16d022d5c31d5b4e5d908e05a8 (diff) | |
parent | 47a6d788ddbab08b2a04c72cd80352aac44090ab (diff) | |
download | rails-37075aa7f5c2c779a981debd21aa8c468cce4d72.tar.gz rails-37075aa7f5c2c779a981debd21aa8c468cce4d72.tar.bz2 rails-37075aa7f5c2c779a981debd21aa8c468cce4d72.zip |
Merge pull request #33654 from kamipo/fix_numericality_validator_2
Fix numericality validator to still use value before type cast except Active Record
-rw-r--r-- | activemodel/CHANGELOG.md | 6 | ||||
-rw-r--r-- | activemodel/lib/active_model/validations/numericality.rb | 15 | ||||
-rw-r--r-- | activemodel/test/cases/validations/numericality_validation_test.rb | 10 | ||||
-rw-r--r-- | activemodel/test/models/topic.rb | 14 |
4 files changed, 41 insertions, 4 deletions
diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md index 4bf96e11b0..0b2fa37787 100644 --- a/activemodel/CHANGELOG.md +++ b/activemodel/CHANGELOG.md @@ -1,3 +1,9 @@ +* Fix numericality validator to still use value before type cast except Active Record. + + Fixes #33651, #33686. + + *Ryuta Kamizono* + * Fix `ActiveModel::Serializers::JSON#as_json` method for timestamps. Before: diff --git a/activemodel/lib/active_model/validations/numericality.rb b/activemodel/lib/active_model/validations/numericality.rb index 3753040316..126a87ac6e 100644 --- a/activemodel/lib/active_model/validations/numericality.rb +++ b/activemodel/lib/active_model/validations/numericality.rb @@ -21,10 +21,17 @@ module ActiveModel def validate_each(record, attr_name, value) came_from_user = :"#{attr_name}_came_from_user?" - if record.respond_to?(came_from_user) && record.public_send(came_from_user) - raw_value = record.read_attribute_before_type_cast(attr_name) - elsif record.respond_to?(:read_attribute) - raw_value = record.read_attribute(attr_name) + if record.respond_to?(came_from_user) + if record.public_send(came_from_user) + raw_value = record.read_attribute_before_type_cast(attr_name) + elsif record.respond_to?(:read_attribute) + raw_value = record.read_attribute(attr_name) + end + else + before_type_cast = :"#{attr_name}_before_type_cast" + if record.respond_to?(before_type_cast) + raw_value = record.public_send(before_type_cast) + end end raw_value ||= value diff --git a/activemodel/test/cases/validations/numericality_validation_test.rb b/activemodel/test/cases/validations/numericality_validation_test.rb index 01b78ae72e..ca3c3bc40d 100644 --- a/activemodel/test/cases/validations/numericality_validation_test.rb +++ b/activemodel/test/cases/validations/numericality_validation_test.rb @@ -262,6 +262,16 @@ class NumericalityValidationTest < ActiveModel::TestCase Person.clear_validators! end + def test_validates_numericality_using_value_before_type_cast_if_possible + Topic.validates_numericality_of :price + + topic = Topic.new(price: 50) + + assert_equal "$50.00", topic.price + assert_equal 50, topic.price_before_type_cast + assert_predicate topic, :valid? + end + def test_validates_numericality_with_exponent_number base = 10_000_000_000_000_000 Topic.validates_numericality_of :approved, less_than_or_equal_to: base diff --git a/activemodel/test/models/topic.rb b/activemodel/test/models/topic.rb index b0af00ee45..db3284f833 100644 --- a/activemodel/test/models/topic.rb +++ b/activemodel/test/models/topic.rb @@ -3,6 +3,11 @@ class Topic include ActiveModel::Validations include ActiveModel::Validations::Callbacks + include ActiveModel::AttributeMethods + include ActiveSupport::NumberHelper + + attribute_method_suffix "_before_type_cast" + define_attribute_method :price def self._validates_default_keys super | [ :message ] @@ -10,6 +15,7 @@ class Topic attr_accessor :title, :author_name, :content, :approved, :created_at attr_accessor :after_validation_performed + attr_writer :price after_validation :perform_after_validation @@ -38,4 +44,12 @@ class Topic def my_validation_with_arg(attr) errors.add attr, "is missing" unless send(attr) end + + def price + number_to_currency @price + end + + def attribute_before_type_cast(attr) + instance_variable_get(:"@#{attr}") + end end |