1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Hash#to_json takes :only or :except options to specific or omit certain hash keys. Enumerable#to_json passes through its options to each element. Closes #9751.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7736 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
Jeremy Kemper 2007-10-04 03:28:42 +00:00
parent a30a1a9d5f
commit b1968708e1
18 changed files with 88 additions and 27 deletions

View file

@ -1,6 +1,6 @@
module ActiveRecord #:nodoc:
module Serialization
def to_json(options = {}, &block)
def to_json(options = {})
JsonSerializer.new(self, options).to_s
end

View file

@ -68,11 +68,12 @@ class DatabaseConnectedJsonEncodingTest < Test::Unit::TestCase
def setup
@david = authors(:david)
@mary = authors(:mary)
end
def test_includes_uses_association_name
json = @david.to_json(:include => :posts)
assert_match %r{"posts": \[}, json
assert_match %r{"id": 1}, json
@ -140,4 +141,37 @@ class DatabaseConnectedJsonEncodingTest < Test::Unit::TestCase
assert_match %r{"favorite_quote": "Constraints are liberating"}, json
assert_equal %r{"favorite_quote": }.match(json).size, 1
end
def test_should_allow_only_option_for_list_of_authors
authors = [@david, @mary]
assert_equal %([{"name": "David"}, {"name": "Mary"}]), authors.to_json(:only => :name)
end
def test_should_allow_except_option_for_list_of_authors
authors = [@david, @mary]
assert_equal %([{"id": 1}, {"id": 2}]), authors.to_json(:except => [:name, :author_address_id])
end
def test_should_allow_includes_for_list_of_authors
authors = [@david, @mary]
json = authors.to_json(
:only => :name,
:include => {
:posts => { :only => :id }
}
)
assert_equal %([{"name": "David", "posts": [{"id": 1}, {"id": 2}, {"id": 4}, {"id": 5}, {"id": 6}]}, {"name": "Mary", "posts": [{"id": 7}]}]), json
end
def test_should_allow_options_for_hash_of_authors
authors_hash = {
1 => @david,
2 => @mary
}
assert_equal %({1: {"name": "David"}}), authors_hash.to_json(:only => [1, :name])
end
end

View file

@ -1,8 +1,10 @@
*SVN*
* Hash#to_json takes :only or :except options to specific or omit certain hash keys. Enumerable#to_json passes through its options to each element. #9751 [Chu Yeow]
* BufferedLogger#auto_flushing = N flushes the log every N messages. Buffers with an array instead of string. [Jeremy Kemper]
* Fixed Date#xmlschema for dates outside the range of what can be created with Time #9744 [gbuesing]
* Fixed Date#xmlschema for dates outside the range of what can be created with Time #9744 [Geoff Buesing]
*2.0.0 [Preview Release]* (September 29th, 2007)

View file

@ -1,5 +1,5 @@
class Date
def to_json #:nodoc:
def to_json(options = nil) #:nodoc:
%("#{strftime("%m/%d/%Y")}")
end
end

View file

@ -1,5 +1,5 @@
class DateTime
def to_json #:nodoc:
def to_json(options = nil) #:nodoc:
%("#{strftime("%m/%d/%Y %H:%M:%S %Z")}")
end
end

View file

@ -1,5 +1,5 @@
module Enumerable
def to_json #:nodoc:
"[#{map { |value| ActiveSupport::JSON.encode(value) } * ', '}]"
def to_json(options = {}) #:nodoc:
"[#{map { |value| ActiveSupport::JSON.encode(value, options) } * ', '}]"
end
end

View file

@ -1,5 +1,5 @@
class FalseClass
def to_json #:nodoc:
def to_json(options = nil) #:nodoc:
'false'
end
end

View file

@ -1,8 +1,16 @@
class Hash
def to_json #:nodoc:
def to_json(options = {}) #:nodoc:
hash_keys = self.keys
if options[:except]
hash_keys = hash_keys - Array(options[:except])
elsif options[:only]
hash_keys = hash_keys & Array(options[:only])
end
returning result = '{' do
result << map do |key, value|
"#{ActiveSupport::JSON.encode(key)}: #{ActiveSupport::JSON.encode(value)}"
result << hash_keys.map do |key|
"#{ActiveSupport::JSON.encode(key)}: #{ActiveSupport::JSON.encode(self[key], options)}"
end * ', '
result << '}'
end

View file

@ -1,5 +1,5 @@
class NilClass
def to_json #:nodoc:
def to_json(options = nil) #:nodoc:
'null'
end
end

View file

@ -1,5 +1,5 @@
class Numeric
def to_json #:nodoc:
def to_json(options = nil) #:nodoc:
to_s
end
end

View file

@ -1,10 +1,6 @@
class Object
# Dumps object in JSON (JavaScript Object Notation). See www.json.org for more info.
#
# Account.find(1).to_json
# => "{attributes: {username: \"foo\", id: \"1\", password: \"bar\"}}"
#
def to_json
ActiveSupport::JSON.encode(instance_values)
def to_json(options = {})
ActiveSupport::JSON.encode(instance_values, options)
end
end

View file

@ -1,5 +1,5 @@
class Regexp
def to_json #:nodoc:
def to_json(options = nil) #:nodoc:
inspect
end
end

View file

@ -17,7 +17,7 @@ module ActiveSupport
end
class String
def to_json #:nodoc:
def to_json(options = nil) #:nodoc:
'"' + gsub(/[\010\f\n\r\t"\\><]/) { |s|
ActiveSupport::JSON::Encoding::ESCAPED_CHARS[s]
}.gsub(/([\xC0-\xDF][\x80-\xBF]|

View file

@ -1,5 +1,5 @@
class Symbol
def to_json #:nodoc:
ActiveSupport::JSON.encode(to_s)
def to_json(options = {}) #:nodoc:
ActiveSupport::JSON.encode(to_s, options)
end
end

View file

@ -1,5 +1,5 @@
class Time
def to_json #:nodoc:
def to_json(options = nil) #:nodoc:
%("#{strftime("%m/%d/%Y %H:%M:%S %Z")}")
end
end

View file

@ -1,5 +1,5 @@
class TrueClass
def to_json #:nodoc:
def to_json(options = nil) #:nodoc:
'true'
end
end

View file

@ -17,9 +17,9 @@ module ActiveSupport
REFERENCE_STACK_VARIABLE = :json_reference_stack #:nodoc:
# Converts a Ruby object into a JSON string.
def encode(value)
def encode(value, options = {})
raise_on_circular_reference(value) do
value.send(:to_json)
value.send(:to_json, options)
end
end

View file

@ -69,8 +69,29 @@ class TestJSONEncoding < Test::Unit::TestCase
assert_equal %w( "$" "A" "A0" "A0B" "_" "a" 0 1 ), object_keys(values.to_json)
end
def test_hash_should_allow_key_filtering_with_only
assert_equal %({"a": 1}), { 'a' => 1, :b => 2, :c => 3 }.to_json(:only => 'a')
end
def test_hash_should_allow_key_filtering_with_except
assert_equal %({"b": 2}), { 'foo' => 'bar', :b => 2, :c => 3 }.to_json(:except => ['foo', :c])
end
protected
def object_keys(json_object)
json_object[1..-2].scan(/([^{}:,\s]+):/).flatten.sort
end
end
uses_mocha 'JsonOptionsTests' do
class JsonOptionsTests < Test::Unit::TestCase
def test_enumerable_should_passthrough_options_to_elements
json_options = { :include => :posts }
ActiveSupport::JSON.expects(:encode).with(1, json_options)
ActiveSupport::JSON.expects(:encode).with(2, json_options)
ActiveSupport::JSON.expects(:encode).with('foo', json_options)
[1, 2, 'foo'].to_json(json_options)
end
end
end