Permalink
Browse files

PG adapter deals with negative money values formatted with parenthesis.

Closes #11899.

Conflicts:
	activerecord/CHANGELOG.md

Backport of 27dc4fa.
  • Loading branch information...
1 parent 26ad789 commit fefb1329e784e2b72ea78cb138007c414c7661dd @senny senny committed Aug 26, 2013
@@ -1,5 +1,11 @@
## unreleased ##
+* PostgreSQL adapter recognizes negative money values formatted with
+ parentheses (eg. `($1.25) # => -1.25`)).
+ Fixes #11899.
+
+ * Yves Senn*
+
* Do not load all child records for inverse case.
currently `post.comments.find(Comment.first.id)` would load all
@@ -38,12 +38,17 @@ def type_cast(value)
class Money < Type
def type_cast(value)
return if value.nil?
+ return value unless String === value
# Because money output is formatted according to the locale, there are two
# cases to consider (note the decimal separators):
# (1) $12,345,678.12
# (2) $12.345.678,12
+ # Negative values are represented as follows:
+ # (3) -$2.55
+ # (4) ($2.55)
+ value.sub!(/^\((.+)\)$/, '-\1') # (4)
case value
when /^-?\D+[\d,]+\.\d{2}$/ # (1)
value.gsub!(/[^-\d.]/, '')
@@ -298,6 +298,14 @@ def test_money_values
assert_equal(-567.89, @second_money.wealth)
end
+ def test_money_type_cast
+ column = PostgresqlMoney.columns.find { |c| c.name == 'wealth' }
+ assert_equal(12345678.12, column.type_cast("$12,345,678.12"))
+ assert_equal(12345678.12, column.type_cast("$12.345.678,12"))
+ assert_equal(-1.15, column.type_cast("-$1.15"))
+ assert_equal(-2.25, column.type_cast("($2.25)"))
+ end
+
def test_create_tstzrange
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
tstzrange = Time.parse('2010-01-01 14:30:00 +0100')...Time.parse('2011-02-02 14:30:00 CDT')

0 comments on commit fefb132

Please sign in to comment.