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:
parent
a30a1a9d5f
commit
b1968708e1
18 changed files with 88 additions and 27 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class Date
|
||||
def to_json #:nodoc:
|
||||
def to_json(options = nil) #:nodoc:
|
||||
%("#{strftime("%m/%d/%Y")}")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class FalseClass
|
||||
def to_json #:nodoc:
|
||||
def to_json(options = nil) #:nodoc:
|
||||
'false'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class NilClass
|
||||
def to_json #:nodoc:
|
||||
def to_json(options = nil) #:nodoc:
|
||||
'null'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class Numeric
|
||||
def to_json #:nodoc:
|
||||
def to_json(options = nil) #:nodoc:
|
||||
to_s
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class Regexp
|
||||
def to_json #:nodoc:
|
||||
def to_json(options = nil) #:nodoc:
|
||||
inspect
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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]|
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class TrueClass
|
||||
def to_json #:nodoc:
|
||||
def to_json(options = nil) #:nodoc:
|
||||
'true'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue