From 134c1156dd5713da41c62ff798fe3979723e64cc Mon Sep 17 00:00:00 2001 From: Godfrey Chan Date: Tue, 5 Nov 2013 19:22:03 -0800 Subject: [PATCH] Fixed Object#as_json and Struct#as_json with options These methods now takes the same options as Hash#as_json, for example: struct = Struct.new(:foo, :bar).new struct.foo = "hello" struct.bar = "world" json = struct.as_json(only: [:foo]) # => {foo: "hello"} This is extracted from PR #11728 from @sergiocampama, see also the discussion in #11460. --- activesupport/CHANGELOG.md | 10 +++++++ .../active_support/core_ext/object/json.rb | 6 ++-- activesupport/test/json/encoding_test.rb | 29 +++++++++++++++++-- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index e718e79877..5d39fa39d9 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,3 +1,13 @@ +* Fixed Object#as_json and Struct#as_json not working properly with options. They now take + the same options as Hash#as_json: + + struct = Struct.new(:foo, :bar).new + struct.foo = "hello" + struct.bar = "world" + json = struct.as_json(only: [:foo]) # => {foo: "hello"} + + *Sergio Campamá*, *Godfrey Chan* + * Added Numeric#in_milliseconds, like 1.hour.in_milliseconds, so we can feed them to JavaScript functions like getTime(). *DHH* diff --git a/activesupport/lib/active_support/core_ext/object/json.rb b/activesupport/lib/active_support/core_ext/object/json.rb index 554da1a2aa..c50cd57c2c 100644 --- a/activesupport/lib/active_support/core_ext/object/json.rb +++ b/activesupport/lib/active_support/core_ext/object/json.rb @@ -20,16 +20,16 @@ end class Object def as_json(options = nil) #:nodoc: if respond_to?(:to_hash) - to_hash + to_hash.as_json(options) else - instance_values + instance_values.as_json(options) end end end class Struct #:nodoc: def as_json(options = nil) - Hash[members.zip(values)] + Hash[members.zip(values)].as_json(options) end end diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb index d549113ff4..ae8b8052ca 100644 --- a/activesupport/test/json/encoding_test.rb +++ b/activesupport/test/json/encoding_test.rb @@ -13,7 +13,7 @@ class TestJSONEncoding < ActiveSupport::TestCase class Hashlike def to_hash - { :a => 1 } + { :foo => "hello", :bar => "world" } end end @@ -61,7 +61,7 @@ class TestJSONEncoding < ActiveSupport::TestCase [ :"a b", %("a b") ]] ObjectTests = [[ Foo.new(1, 2), %({\"a\":1,\"b\":2}) ]] - HashlikeTests = [[ Hashlike.new, %({\"a\":1}) ]] + HashlikeTests = [[ Hashlike.new, %({\"bar\":\"world\",\"foo\":\"hello\"}) ]] CustomTests = [[ Custom.new, '"custom"' ]] RegexpTests = [[ /^a/, '"(?-mix:^a)"' ], [/^\w{1,2}[a-z]+/ix, '"(?ix-m:^\\\\w{1,2}[a-z]+)"']] @@ -204,6 +204,31 @@ class TestJSONEncoding < ActiveSupport::TestCase end end + def test_hash_like_with_options + h = Hashlike.new + json = h.to_json :only => [:foo] + + assert_equal({"foo"=>"hello"}, JSON.parse(json)) + end + + def test_object_to_json_with_options + obj = Object.new + obj.instance_variable_set :@foo, "hello" + obj.instance_variable_set :@bar, "world" + json = obj.to_json :only => ["foo"] + + assert_equal({"foo"=>"hello"}, JSON.parse(json)) + end + + def test_struct_to_json_with_options + struct = Struct.new(:foo, :bar).new + struct.foo = "hello" + struct.bar = "world" + json = struct.to_json :only => [:foo] + + assert_equal({"foo"=>"hello"}, JSON.parse(json)) + end + def test_hash_should_pass_encoding_options_to_children_in_as_json person = { :name => 'John',