From b9ec47da00e7f5e159ff130441585c3b42e41849 Mon Sep 17 00:00:00 2001 From: Angelo capilleri Date: Fri, 8 Jun 2012 10:09:28 +0200 Subject: Validates_numericality_of is skipped when changing 0 to to non-empty string This happens when A has_many many B and A accepts_nested_attributes B that has a numeric colum with initial 0 value. So a.update_attributes({:b_attributes => { :id => b.id, :numeric => 'foo' }}) passes the validation test but, the value of :numeric doesn't change. his commit forces that the update fails with the above conditions. Fixes #6393 Fixes #2331 --- .../lib/active_record/attribute_methods/dirty.rb | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb index f8a40ad520..032aefd8c0 100644 --- a/activerecord/lib/active_record/attribute_methods/dirty.rb +++ b/activerecord/lib/active_record/attribute_methods/dirty.rb @@ -77,11 +77,8 @@ module ActiveRecord def _field_changed?(attr, old, value) if column = column_for_attribute(attr) - if column.number? && column.null && (old.nil? || old == 0) && value.blank? - # For nullable numeric columns, NULL gets stored in database for blank (i.e. '') values. - # Hence we don't record it as a change if the value changes from nil to ''. - # If an old value of 0 is set to '' we want this to get changed to nil as otherwise it'll - # be typecast back to 0 (''.to_i => 0) + if numeric_changes_from_nil_to_empty_string?(column, old, value) || + numeric_changes_from_zero_to_string?(column, old, value) value = nil else value = column.type_cast(value) @@ -90,6 +87,19 @@ module ActiveRecord old != value end + + def numeric_changes_from_nil_to_empty_string?(column, old, value) + # For nullable numeric columns, NULL gets stored in database for blank (i.e. '') values. + # Hence we don't record it as a change if the value changes from nil to ''. + # If an old value of 0 is set to '' we want this to get changed to nil as otherwise it'll + # be typecast back to 0 (''.to_i => 0) + column.number? && column.null && (old.nil? || old == 0) && value.blank? + end + + def numeric_changes_from_zero_to_string?(column, old, value) + # For numeric columns with old 0 and value non-empty string + column.number? && old == 0 && value != '0' && !value.blank? && !old.nil? + end end end end -- cgit v1.2.3 From 17ce0b13e66e7e0b6bc0a86f7c397453aa95729f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Tue, 19 Jun 2012 01:53:34 -0300 Subject: Refactor the conditionals --- activerecord/lib/active_record/attribute_methods/dirty.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb index 032aefd8c0..a85b6b3b82 100644 --- a/activerecord/lib/active_record/attribute_methods/dirty.rb +++ b/activerecord/lib/active_record/attribute_methods/dirty.rb @@ -77,8 +77,8 @@ module ActiveRecord def _field_changed?(attr, old, value) if column = column_for_attribute(attr) - if numeric_changes_from_nil_to_empty_string?(column, old, value) || - numeric_changes_from_zero_to_string?(column, old, value) + if column.number? && (changes_from_nil_to_empty_string?(column, old, value) || + changes_from_zero_to_string?(column, old, value)) value = nil else value = column.type_cast(value) @@ -88,17 +88,17 @@ module ActiveRecord old != value end - def numeric_changes_from_nil_to_empty_string?(column, old, value) + def changes_from_nil_to_empty_string?(column, old, value) # For nullable numeric columns, NULL gets stored in database for blank (i.e. '') values. # Hence we don't record it as a change if the value changes from nil to ''. # If an old value of 0 is set to '' we want this to get changed to nil as otherwise it'll # be typecast back to 0 (''.to_i => 0) - column.number? && column.null && (old.nil? || old == 0) && value.blank? + column.null && (old.nil? || old == 0) && value.blank? end - def numeric_changes_from_zero_to_string?(column, old, value) - # For numeric columns with old 0 and value non-empty string - column.number? && old == 0 && value != '0' && !value.blank? && !old.nil? + def changes_from_zero_to_string?(column, old, value) + # For columns with old 0 and value non-empty string + old == 0 && value.present? && value != '0' end end end -- cgit v1.2.3