提交 47a6d788 编写于 作者: R Ryuta Kamizono

Fix numericality validator to still use value before type cast except Active Record

The purpose of fe9547b6 is to work type casting to value from database.

But that was caused not to use the value before type cast even except
Active Record.

There we never guarantees that the value before type cast was going to
the used in this validation, but we should not change the behavior
unless there is some particular reason.

To restore original behavior, still use the value before type cast if
`came_from_user?` is undefined (i.e. except Active Record).

Fixes #33651.
Fixes #33686.
上级 a0b57bbb
* 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:
......
......@@ -21,10 +21,17 @@ def check_validity!
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
......
......@@ -262,6 +262,16 @@ def test_validates_numericality_of_for_ruby_class
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
......
......@@ -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 @@ def self._validates_default_keys
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 @@ def my_validation
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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册