diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index 9c7078b9a494f66622708207e65e296a95cb29c4..172c6972a6150a49d69335ea8e2fd28b523e235d 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -19,6 +19,22 @@ *Godfrey Chan* +* Removed the old pure-Ruby JSON encoder and switched to a new encoder based on the built-in JSON + gem. + + Support for encoding `BigDecimal` as a JSON number, as well as defining custom `encode_json` + methods to control the JSON output has been **removed from core**. The new encoder will always + encode BigDecimals as `String`s and ignore any custom `encode_json` methods. + + The old encoder has been extracted into the `activesupport-json_encoder` gem. Installing that + gem will bring back the ability to encode `BigDecimal`s as numbers as well as `encode_json` + support. + + Setting the related configuration `ActiveSupport.encode_big_decimal_as_string` without the + `activesupport-json_encoder` gem installed will raise an error. + + *Godfrey Chan* + * Add `ActiveSupport::Testing::TimeHelpers#travel` and `#travel_to`. These methods change current time to the given time or time difference by stubbing `Time.now` and `Date.today` to return the time or date after the difference calculation, or the time or date that got passed into the diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb index eb25ef7a4c7cee2ac39af697a6916574eb7bdb32..060dcb6995ed84db4d9c0659231bacc22adabe2f 100644 --- a/activesupport/lib/active_support/json/encoding.rb +++ b/activesupport/lib/active_support/json/encoding.rb @@ -5,6 +5,7 @@ module ActiveSupport class << self delegate :use_standard_json_time_format, :use_standard_json_time_format=, :escape_html_entities_in_json, :escape_html_entities_in_json=, + :encode_big_decimal_as_string, :encode_big_decimal_as_string=, :json_encoder, :json_encoder=, :to => :'ActiveSupport::JSON::Encoding' end @@ -113,6 +114,32 @@ class << self # in +Object#to_json+ and +ActiveSupport::JSON.encode+. attr_accessor :json_encoder + def encode_big_decimal_as_string=(as_string) + message = \ + "The JSON encoder in Rails 4.1 no longer supports encoding BigDecimals as JSON numbers. Instead, " \ + "the new encoder will always encode them as strings.\n\n" \ + "You are seeing this error because you have 'active_support.encode_big_decimal_as_string' in " \ + "your configuration file. If you have been setting this to true, you can safely remove it from " \ + "your configuration. Otherwise, you should add the 'activesupport-json_encoder' gem to your " \ + "Gemfile in order to restore this functionality." + + raise NotImplementedError, message + end + + def encode_big_decimal_as_string + message = \ + "The JSON encoder in Rails 4.1 no longer supports encoding BigDecimals as JSON numbers. Instead, " \ + "the new encoder will always encode them as strings.\n\n" \ + "You are seeing this error because you are trying to check the value of the related configuration, " \ + "'active_support.encode_big_decimal_as_string'. If your application depends on this option, you should " \ + "add the 'activesupport-json_encoder' gem to your Gemfile. For now, this option will always be true. " \ + "In the future, it will be removed from Rails, so you should stop checking its value." + + ActiveSupport::Deprecation.warn message + + true + end + # Deprecate CircularReferenceError def const_missing(name) if name == :CircularReferenceError diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb index 79e639b5088a690b1533920aa02dbea907f25269..78cf4819f93565468ac42b688589616a62b67483 100644 --- a/activesupport/test/json/encoding_test.rb +++ b/activesupport/test/json/encoding_test.rb @@ -172,6 +172,22 @@ def test_wide_utf8_roundtrip assert_equal "𐒑", decoded_hash['string'] end + def test_reading_encode_big_decimal_as_string_option + assert_deprecated do + assert ActiveSupport.encode_big_decimal_as_string + end + end + + def test_setting_deprecated_encode_big_decimal_as_string_option + assert_raise(NotImplementedError) do + ActiveSupport.encode_big_decimal_as_string = true + end + + assert_raise(NotImplementedError) do + ActiveSupport.encode_big_decimal_as_string = false + end + end + def test_exception_raised_when_encoding_circular_reference_in_array a = [1] a << a