Skip to content
Browse files

Fix numericality validator not to be affected by custom getter

Since fe9547b, numericality validator would parse raw value only when a
value came from user to work type casting to a value from database.

But that was caused a regression that the validator would work against
getter value instead of parsed raw value, a getter is sometimes
customized by people. #33550

There we never guarantees that the value before type cast was going to
the used in this validation (actually here is only place that getter
value might not be used), but we should not change the behavior unless
there is some particular reason.

The purpose of fe9547b is to work type casting to a value from
database. We could achieve the purpose by using `read_attribute`,
without using getter value.

Fixes #33550.
  • Loading branch information...
kamipo committed Aug 10, 2018
1 parent f2970a0 commit 2fece9036d8ea778fca63a0d5df9a9dfc330dfa5
@@ -23,6 +23,8 @@ def validate_each(record, attr_name, value)

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)
raw_value ||= value

@@ -781,7 +781,7 @@ def test_scoped_find_on_through_association_doesnt_return_read_only_records

def test_has_many_through_polymorphic_has_manys_works
assert_equal [10, 20].to_set, pirates(:redbeard)
assert_equal ["$10.00", "$20.00"].to_set, pirates(:redbeard)

def test_symbols_as_keys
@@ -3,11 +3,11 @@
require "cases/helper"
require "models/topic"
require "models/reply"
require "models/person"
require "models/developer"
require "models/computer"
require "models/parrot"
require "models/company"
require "models/price_estimate"

class ValidationsTest < ActiveRecord::TestCase
fixtures :topics, :developers
@@ -183,6 +183,22 @@ def self.model_name
assert_not_predicate BigDecimal("97.179")), :valid?

def test_numericality_validator_wont_be_affected_by_custom_getter
price_estimate = 50)

assert_equal "$50.00", price_estimate.price
assert_equal 50, price_estimate.price_before_type_cast
assert_equal 50, price_estimate.read_attribute(:price)

assert_predicate price_estimate, :price_came_from_user?
assert_predicate price_estimate, :valid?!

assert_not_predicate price_estimate, :price_came_from_user?
assert_predicate price_estimate, :valid?

def test_acceptance_validator_doesnt_require_db_connection
klass = do
self.table_name = "posts"
@@ -1,6 +1,14 @@
# frozen_string_literal: true

class PriceEstimate < ActiveRecord::Base
include ActiveSupport::NumberHelper

belongs_to :estimate_of, polymorphic: true
belongs_to :thing, polymorphic: true

validates_numericality_of :price

def price
number_to_currency super

0 comments on commit 2fece90

Please sign in to comment.
You can’t perform that action at this time.