diff options
-rw-r--r-- | activemodel/lib/active_model/validations/numericality.rb | 11 | ||||
-rw-r--r-- | activerecord/lib/active_record/attribute_methods/dirty.rb | 12 | ||||
-rw-r--r-- | activerecord/test/cases/validations_test.rb | 13 |
3 files changed, 30 insertions, 6 deletions
diff --git a/activemodel/lib/active_model/validations/numericality.rb b/activemodel/lib/active_model/validations/numericality.rb index 13d6a966c0..4ba4e3e8f7 100644 --- a/activemodel/lib/active_model/validations/numericality.rb +++ b/activemodel/lib/active_model/validations/numericality.rb @@ -23,6 +23,10 @@ module ActiveModel raw_value = record.send(before_type_cast) if record.respond_to?(before_type_cast) raw_value ||= value + if record_attribute_changed_in_place?(record, attr_name) + raw_value = value + end + return if options[:allow_nil] && raw_value.nil? unless value = parse_raw_value_as_a_number(raw_value) @@ -86,6 +90,13 @@ module ActiveModel options[:only_integer] end end + + private + + def record_attribute_changed_in_place?(record, attr_name) + record.respond_to?(:attribute_changed_in_place?) && + record.attribute_changed_in_place?(attr_name.to_s) + end end module HelperMethods diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb index 9ba46ec4c7..033e71f7b9 100644 --- a/activerecord/lib/active_record/attribute_methods/dirty.rb +++ b/activerecord/lib/active_record/attribute_methods/dirty.rb @@ -69,6 +69,11 @@ module ActiveRecord end end + def attribute_changed_in_place?(attr_name) + old_value = original_raw_attribute(attr_name) + @attributes[attr_name].changed_in_place_from?(old_value) + end + private def calculate_changes_from_defaults @@ -141,15 +146,10 @@ module ActiveRecord def changed_in_place self.class.attribute_names.select do |attr_name| - changed_in_place?(attr_name) + attribute_changed_in_place?(attr_name) end end - def changed_in_place?(attr_name) - old_value = original_raw_attribute(attr_name) - @attributes[attr_name].changed_in_place_from?(old_value) - end - def original_raw_attribute(attr_name) original_raw_attributes.fetch(attr_name) do read_attribute_before_type_cast(attr_name) diff --git a/activerecord/test/cases/validations_test.rb b/activerecord/test/cases/validations_test.rb index db8159eff8..959c58aa85 100644 --- a/activerecord/test/cases/validations_test.rb +++ b/activerecord/test/cases/validations_test.rb @@ -149,4 +149,17 @@ class ValidationsTest < ActiveRecord::TestCase assert_equal 1, Company.validators_on(:name).size end + def test_numericality_validation_with_mutation + Topic.class_eval do + attribute :wibble, ActiveRecord::Type::String.new + validates_numericality_of :wibble, only_integer: true + end + + topic = Topic.new(wibble: '123-4567') + topic.wibble.gsub!('-', '') + + assert topic.valid? + ensure + Topic.reset_column_information + end end |