From aa062318c451512035c10898a1af95943b1a3803 Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Wed, 27 Apr 2016 05:55:32 +0900 Subject: Avoid type casting in uniqueness validator Type casting in uniqueness validator is for a string value truncation. It was removed at #23523. --- activerecord/lib/active_record/validations/uniqueness.rb | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb index 1f59276137..de8512751a 100644 --- a/activerecord/lib/active_record/validations/uniqueness.rb +++ b/activerecord/lib/active_record/validations/uniqueness.rb @@ -32,6 +32,7 @@ module ActiveRecord record.errors.add(attribute, :taken, error_options) end + rescue RangeError end protected @@ -65,8 +66,6 @@ module ActiveRecord column = klass.columns_hash[attribute_name] cast_type = klass.type_for_attribute(attribute_name) - value = cast_type.serialize(value) - value = klass.connection.type_cast(value) comparison = if !options[:case_sensitive] && !value.nil? # will use SQL LOWER function before comparison, unless it detects a case insensitive collation @@ -77,11 +76,9 @@ module ActiveRecord if value.nil? klass.unscoped.where(comparison) else - bind = Relation::QueryAttribute.new(attribute_name, value, Type::Value.new) + bind = Relation::QueryAttribute.new(attribute_name, value, cast_type) klass.unscoped.where(comparison, bind) end - rescue RangeError - klass.none end def scope_relation(record, table, relation) -- cgit v1.2.3 From 1cf467b7a31749ccb3fc2a8ac89c5218c95e7d70 Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Sat, 4 Jun 2016 15:03:47 +0900 Subject: Prevent `RangeError` for `FinderMethods#exists?` `FinderMethods#exists?` should return a boolean rather than raising an exception. `UniquenessValidator#build_relation` catches a `RangeError` because it includes type casting due to a string value truncation. But a string value truncation was removed at #23523 then type casting in `build_relation` is no longer necessary. aa06231 removes type casting in `build_relation` then a `RangeError` moves to `relation.exists?`. This change will remove the catching a `RangeError`. --- activerecord/lib/active_record/relation/finder_methods.rb | 4 +++- activerecord/lib/active_record/validations/uniqueness.rb | 1 - activerecord/test/cases/finder_test.rb | 6 ++---- 3 files changed, 5 insertions(+), 6 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index 87eea8277a..0948e55ae3 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -333,6 +333,8 @@ module ActiveRecord end connection.select_value(relation, "#{name} Exists", relation.bound_attributes) ? true : false + rescue RangeError + false end # This method is called whenever no records are found with either a single @@ -579,7 +581,7 @@ module ActiveRecord # e.g., reverse_order.offset(index-1).first end end - + private def find_nth_with_limit_and_offset(index, limit, offset:) # :nodoc: diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb index de8512751a..ec9f498c40 100644 --- a/activerecord/lib/active_record/validations/uniqueness.rb +++ b/activerecord/lib/active_record/validations/uniqueness.rb @@ -32,7 +32,6 @@ module ActiveRecord record.errors.add(attribute, :taken, error_options) end - rescue RangeError end protected diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index 374a8ba199..6eaaa30cd0 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -173,11 +173,9 @@ class FinderTest < ActiveRecord::TestCase end end - def test_exists_fails_when_parameter_has_invalid_type - assert_raises(ActiveModel::RangeError) do - assert_equal false, Topic.exists?(("9"*53).to_i) # number that's bigger than int - end + def test_exists_returns_false_when_parameter_has_invalid_type assert_equal false, Topic.exists?("foo") + assert_equal false, Topic.exists?(("9"*53).to_i) # number that's bigger than int end def test_exists_does_not_select_columns_without_alias -- cgit v1.2.3