Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #10497 from senny/10485_does_not_coerce_strings

coerce strings when reading attributes
  • Loading branch information...
commit 0e144bebc6d979780c3243537673ff553ffb37f5 2 parents 4d24c15 + d9314b4
@senny senny authored
View
11 activerecord/CHANGELOG.md
@@ -1,3 +1,14 @@
+* Coerce strings when reading attributes.
+ Fixes #10485.
+
+ Example:
+
+ book = Book.new(title: 12345)
+ book.save!
+ book.title # => "12345"
+
+ *Yves Senn*
+
* Deprecate half-baked support for PostgreSQL range values with excluding beginnings.
We currently map PostgreSQL ranges to Ruby ranges. This conversion is not fully
possible because the Ruby range does not support excluded beginnings.
View
10 activerecord/lib/active_record/connection_adapters/column.rb
@@ -87,7 +87,7 @@ def type_cast_for_write(value)
end
end
- # Casts value (which is a String) to an appropriate instance.
+ # Casts value to an appropriate instance.
def type_cast(value)
return nil if value.nil?
return coder.load(value) if encoded?
@@ -95,7 +95,13 @@ def type_cast(value)
klass = self.class
case type
- when :string, :text then value
+ when :string, :text
+ case value
+ when TrueClass; "1"
+ when FalseClass; "0"
+ else
+ value.to_s
+ end
when :integer then klass.value_to_integer(value)
when :float then value.to_f
when :decimal then klass.value_to_decimal(value)
View
18 activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
@@ -18,6 +18,14 @@ def type_cast(value)
end
end
+ class Text < Type
+ def type_cast(value)
+ return if value.nil?
+
+ value.to_s
+ end
+ end
+
class Bit < Type
def type_cast(value)
if String === value
@@ -329,7 +337,7 @@ def self.registered_type?(name)
alias_type 'oid', 'int2'
register_type 'numeric', OID::Decimal.new
- register_type 'text', OID::Identity.new
+ register_type 'text', OID::Text.new
alias_type 'varchar', 'text'
alias_type 'char', 'text'
alias_type 'bpchar', 'text'
@@ -355,13 +363,13 @@ def self.registered_type?(name)
register_type 'date', OID::Date.new
register_type 'time', OID::Time.new
- register_type 'path', OID::Identity.new
+ register_type 'path', OID::Text.new
register_type 'point', OID::Point.new
- register_type 'polygon', OID::Identity.new
- register_type 'circle', OID::Identity.new
+ register_type 'polygon', OID::Text.new
+ register_type 'circle', OID::Text.new
register_type 'hstore', OID::Hstore.new
register_type 'json', OID::Json.new
- register_type 'ltree', OID::Identity.new
+ register_type 'ltree', OID::Text.new
register_type 'cidr', OID::Cidr.new
alias_type 'inet', 'cidr'
View
18 activerecord/test/cases/attribute_methods_test.rb
@@ -555,6 +555,24 @@ def test_accessing_cached_attributes_caches_the_converted_values_and_nothing_els
end
end
+ def test_converted_values_are_returned_after_assignment
+ developer = Developer.new(name: 1337, salary: "50000")
+
+ assert_equal "50000", developer.salary_before_type_cast
+ assert_equal 1337, developer.name_before_type_cast
+
+ assert_equal 50000, developer.salary
+ assert_equal "1337", developer.name
+
+ developer.save!
+
+ assert_equal "50000", developer.salary_before_type_cast
+ assert_equal 1337, developer.name_before_type_cast
+
+ assert_equal 50000, developer.salary
+ assert_equal "1337", developer.name
+ end
+
def test_write_nil_to_time_attributes
in_time_zone "Pacific Time (US & Canada)" do
record = @target.new
Please sign in to comment.
Something went wrong with that request. Please try again.