Skip to content

Commit

Permalink
allow_nil should work for casted value in NumericalityValidator
Browse files Browse the repository at this point in the history
It is a regression for 4cc438a.

`NumericalityValidator` basically takes the value before typecasting,
but `allow_nil` should work for the typecasted value for the
compatibility.

Fixes rails#40750.
  • Loading branch information
kamipo committed Dec 8, 2020
1 parent ef61c9c commit 1dee499
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 6 deletions.
6 changes: 4 additions & 2 deletions activemodel/lib/active_model/validations/numericality.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ def allow_only_integer?(record)
end

def read_attribute_for_validation(record, attr_name)
return super if record_attribute_changed_in_place?(record, attr_name)
value = super

return value if record_attribute_changed_in_place?(record, attr_name)

came_from_user = :"#{attr_name}_came_from_user?"

Expand All @@ -126,7 +128,7 @@ def read_attribute_for_validation(record, attr_name)
end
end

raw_value || super
raw_value || value
end

def record_attribute_changed_in_place?(record, attr_name)
Expand Down
11 changes: 7 additions & 4 deletions activemodel/lib/active_model/validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,10 @@ def initialize(options)
# override +validate_each+ with validation logic.
def validate(record)
attributes.each do |attribute|
value = read_attribute_for_validation(record, attribute)
next if (value.nil? && options[:allow_nil]) || (value.blank? && options[:allow_blank])
validate_each(record, attribute, value)
catch(:allowed) do
value = read_attribute_for_validation(record, attribute)
validate_each(record, attribute, value)
end
end
end

Expand All @@ -167,7 +168,9 @@ def check_validity!

private
def read_attribute_for_validation(record, attr_name)
record.read_attribute_for_validation(attr_name)
value = record.read_attribute_for_validation(attr_name)
throw(:allowed) if (value.nil? && options[:allow_nil]) || (value.blank? && options[:allow_blank])
value
end
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,12 @@ def test_aliased_attribute

assert_not_predicate subject, :valid?
end

def test_allow_nil_works_for_casted_value
model_class.validates_numericality_of(:bank_balance, greater_than: 0, allow_nil: true)

subject = model_class.new(bank_balance: "")

assert_predicate subject, :valid?
end
end

0 comments on commit 1dee499

Please sign in to comment.