Skip to content

Commit

Permalink
Merge pull request #10497 from senny/10485_does_not_coerce_strings
Browse files Browse the repository at this point in the history
coerce strings when reading attributes
  • Loading branch information
senny committed Feb 24, 2014
2 parents 4d24c15 + d9314b4 commit 0e144be
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 7 deletions.
11 changes: 11 additions & 0 deletions activerecord/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
10 changes: 8 additions & 2 deletions activerecord/lib/active_record/connection_adapters/column.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,21 @@ 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?

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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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'
Expand All @@ -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'
Expand Down
18 changes: 18 additions & 0 deletions activerecord/test/cases/attribute_methods_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 0e144be

Please sign in to comment.