jbuilder 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +28 -4
- data/jbuilder.gemspec +1 -1
- data/lib/jbuilder.rb +14 -5
- data/lib/jbuilder/jbuilder_template.rb +2 -2
- data/test/jbuilder_test.rb +23 -2
- metadata +25 -18
- checksums.yaml +0 -15
data/README.md
CHANGED
@@ -59,7 +59,7 @@ To define attribute and structure names dynamically, use the `set!` method:
|
|
59
59
|
|
60
60
|
``` ruby
|
61
61
|
json.set! :author do
|
62
|
-
json.set! :name,
|
62
|
+
json.set! :name, 'David'
|
63
63
|
end
|
64
64
|
|
65
65
|
# => "author": { "name": "David" }
|
@@ -77,6 +77,16 @@ end
|
|
77
77
|
# => [ { "name": "David", "age": 32 }, { "name": "Jamie", "age": 31 } ]
|
78
78
|
```
|
79
79
|
|
80
|
+
You can also extract attributes from array directly.
|
81
|
+
|
82
|
+
``` ruby
|
83
|
+
# @people = People.all
|
84
|
+
json.array! @people, :id, :name
|
85
|
+
|
86
|
+
# => [ { "id": 1, "name": "David" }, { "id": 2, "name": "Jamie" } ]
|
87
|
+
```
|
88
|
+
|
89
|
+
|
80
90
|
Jbuilder objects can be directly nested inside each other. Useful for composing objects.
|
81
91
|
|
82
92
|
``` ruby
|
@@ -99,7 +109,7 @@ class Company
|
|
99
109
|
end
|
100
110
|
end
|
101
111
|
|
102
|
-
company = Company.new(
|
112
|
+
company = Company.new('Doodle Corp', Person.new('John Stobs', 58))
|
103
113
|
company.to_builder.target!
|
104
114
|
|
105
115
|
# => {"name":"Doodle Corp","president":{"name":"John Stobs","age":58}}
|
@@ -126,14 +136,28 @@ end
|
|
126
136
|
# RAILS_ROOT/app/views/api/comments/_comments, and set a local variable
|
127
137
|
# 'comments' with all this message's comments, which you can use inside
|
128
138
|
# the partial.
|
129
|
-
json.partial!
|
139
|
+
json.partial! 'api/comments/comments', comments: @message.comments
|
140
|
+
```
|
141
|
+
|
142
|
+
You can explicitly make Jbuilder object return null if you want:
|
143
|
+
|
144
|
+
``` ruby
|
145
|
+
json.extract! @post, :id, :title, :content, :published_at
|
146
|
+
json.author do
|
147
|
+
if @post.anonymous?
|
148
|
+
json.null! # or json.nil!
|
149
|
+
else
|
150
|
+
json.first_name @post.author_first_name
|
151
|
+
json.last_name @post.author_last_name
|
152
|
+
end
|
153
|
+
end
|
130
154
|
```
|
131
155
|
|
132
156
|
Keys can be auto formatted using `key_format!`, this can be used to convert keynames from the standard ruby_format to CamelCase:
|
133
157
|
|
134
158
|
``` ruby
|
135
159
|
json.key_format! :camelize => :lower
|
136
|
-
json.first_name
|
160
|
+
json.first_name 'David'
|
137
161
|
|
138
162
|
# => { "firstName": "David" }
|
139
163
|
```
|
data/jbuilder.gemspec
CHANGED
data/lib/jbuilder.rb
CHANGED
@@ -14,6 +14,12 @@ rescue LoadError
|
|
14
14
|
end
|
15
15
|
|
16
16
|
class Jbuilder < JbuilderProxy
|
17
|
+
class NullError < ::NoMethodError
|
18
|
+
def initialize(key)
|
19
|
+
super "Failed to add #{key.to_s.inspect} property to null object"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
17
23
|
class KeyFormatter
|
18
24
|
def initialize(*args)
|
19
25
|
@format = ::ActiveSupport::OrderedHash.new
|
@@ -52,7 +58,7 @@ class Jbuilder < JbuilderProxy
|
|
52
58
|
@@key_formatter = KeyFormatter.new
|
53
59
|
@@ignore_nil = false
|
54
60
|
|
55
|
-
def initialize(*args)
|
61
|
+
def initialize(*args, &block)
|
56
62
|
@attributes = ::ActiveSupport::OrderedHash.new
|
57
63
|
|
58
64
|
options = args.extract_options!
|
@@ -67,14 +73,14 @@ class Jbuilder < JbuilderProxy
|
|
67
73
|
'arguments is deprecated. Use hash syntax instead.'
|
68
74
|
end
|
69
75
|
|
70
|
-
yield self if
|
76
|
+
yield self if block
|
71
77
|
end
|
72
78
|
|
73
79
|
BLANK = ::Object.new
|
74
80
|
|
75
81
|
def set!(key, value = BLANK, *args, &block)
|
76
82
|
|
77
|
-
result = if
|
83
|
+
result = if block
|
78
84
|
if BLANK != value
|
79
85
|
# json.comments @post.comments { |comment| ... }
|
80
86
|
# { "comments": [ { ... }, { ... } ] }
|
@@ -224,9 +230,11 @@ class Jbuilder < JbuilderProxy
|
|
224
230
|
# json.array! [1, 2, 3]
|
225
231
|
#
|
226
232
|
# [1,2,3]
|
227
|
-
def array!(collection, &block)
|
228
|
-
@attributes = if
|
233
|
+
def array!(collection, *attributes, &block)
|
234
|
+
@attributes = if block
|
229
235
|
_map_collection(collection) { |element| block.arity == 2 ? block[self, element] : block[element] }
|
236
|
+
elsif attributes.any?
|
237
|
+
_map_collection(collection) { |element| extract! element, *attributes }
|
230
238
|
else
|
231
239
|
collection
|
232
240
|
end
|
@@ -286,6 +294,7 @@ class Jbuilder < JbuilderProxy
|
|
286
294
|
private
|
287
295
|
|
288
296
|
def _set_value(key, value)
|
297
|
+
raise NullError, key if @attributes.nil?
|
289
298
|
unless @ignore_nil && value.nil?
|
290
299
|
@attributes[@key_formatter.format(key)] = value
|
291
300
|
end
|
@@ -9,9 +9,9 @@ class JbuilderTemplate < Jbuilder
|
|
9
9
|
when ::Hash
|
10
10
|
options[:locals] ||= {}
|
11
11
|
options[:locals].merge!(:json => self)
|
12
|
-
@context.render(options.reverse_merge(:
|
12
|
+
@context.render(options.reverse_merge(:handlers => [:jbuilder]))
|
13
13
|
else # String
|
14
|
-
@context.render(:partial => options, :locals => locals.merge(:json => self), :
|
14
|
+
@context.render(:partial => options, :locals => locals.merge(:json => self), :handlers => [:jbuilder])
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
data/test/jbuilder_test.rb
CHANGED
@@ -325,8 +325,9 @@ class JbuilderTest < ActiveSupport::TestCase
|
|
325
325
|
end
|
326
326
|
end
|
327
327
|
|
328
|
-
|
329
|
-
|
328
|
+
parsed = MultiJson.load(json)
|
329
|
+
assert_equal 'David', parsed.first['names'].last
|
330
|
+
assert_not_equal 'hello', parsed.first['not_in_json']
|
330
331
|
end
|
331
332
|
|
332
333
|
test 'nested jbuilder objects' do
|
@@ -367,6 +368,20 @@ class JbuilderTest < ActiveSupport::TestCase
|
|
367
368
|
assert_equal 'world', parsed.second['content']
|
368
369
|
end
|
369
370
|
|
371
|
+
test 'extract attributes directly from array' do
|
372
|
+
comments = [ Comment.new('hello', 1), Comment.new('world', 2) ]
|
373
|
+
|
374
|
+
json = Jbuilder.encode do |json|
|
375
|
+
json.array! comments, :content, :id
|
376
|
+
end
|
377
|
+
|
378
|
+
parsed = MultiJson.load(json)
|
379
|
+
assert_equal 'hello', parsed.first['content']
|
380
|
+
assert_equal 1, parsed.first['id']
|
381
|
+
assert_equal 'world', parsed.second['content']
|
382
|
+
assert_equal 2, parsed.second['id']
|
383
|
+
end
|
384
|
+
|
370
385
|
test 'empty top-level array' do
|
371
386
|
comments = []
|
372
387
|
|
@@ -585,4 +600,10 @@ class JbuilderTest < ActiveSupport::TestCase
|
|
585
600
|
json.null!
|
586
601
|
assert_nil json.attributes!
|
587
602
|
end
|
603
|
+
|
604
|
+
test 'throws meaningfull error when on trying to add properties to null' do
|
605
|
+
json = Jbuilder.new
|
606
|
+
json.null!
|
607
|
+
assert_raise(Jbuilder::NullError) { json.foo 'bar' }
|
608
|
+
end
|
588
609
|
end
|
metadata
CHANGED
@@ -1,57 +1,64 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jbuilder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease:
|
5
|
+
version: 1.4.0
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- David Heinemeier Hansson
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2013-04
|
12
|
+
date: 2013-05-04 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
|
-
prerelease: false
|
15
15
|
name: activesupport
|
16
|
-
|
16
|
+
type: :runtime
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
17
19
|
requirements:
|
18
20
|
- - ! '>='
|
19
21
|
- !ruby/object:Gem::Version
|
20
22
|
version: 3.0.0
|
21
|
-
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
22
26
|
requirements:
|
23
27
|
- - ! '>='
|
24
28
|
- !ruby/object:Gem::Version
|
25
29
|
version: 3.0.0
|
26
|
-
type: :runtime
|
27
30
|
- !ruby/object:Gem::Dependency
|
28
|
-
prerelease: false
|
29
31
|
name: multi_json
|
30
|
-
|
32
|
+
type: :runtime
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
31
35
|
requirements:
|
32
36
|
- - ! '>='
|
33
37
|
- !ruby/object:Gem::Version
|
34
38
|
version: 1.2.0
|
35
|
-
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
36
42
|
requirements:
|
37
43
|
- - ! '>='
|
38
44
|
- !ruby/object:Gem::Version
|
39
45
|
version: 1.2.0
|
40
|
-
type: :runtime
|
41
46
|
- !ruby/object:Gem::Dependency
|
42
|
-
prerelease: false
|
43
47
|
name: rake
|
44
|
-
|
48
|
+
type: :development
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
45
51
|
requirements:
|
46
52
|
- - ~>
|
47
53
|
- !ruby/object:Gem::Version
|
48
54
|
version: 10.0.3
|
49
|
-
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
50
58
|
requirements:
|
51
59
|
- - ~>
|
52
60
|
- !ruby/object:Gem::Version
|
53
61
|
version: 10.0.3
|
54
|
-
type: :development
|
55
62
|
description:
|
56
63
|
email: david@37signals.com
|
57
64
|
executables: []
|
@@ -81,30 +88,30 @@ files:
|
|
81
88
|
homepage:
|
82
89
|
licenses:
|
83
90
|
- MIT
|
84
|
-
metadata: {}
|
85
91
|
post_install_message:
|
86
92
|
rdoc_options: []
|
87
93
|
require_paths:
|
88
94
|
- lib
|
89
95
|
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
90
97
|
requirements:
|
91
98
|
- - ! '>='
|
92
99
|
- !ruby/object:Gem::Version
|
93
100
|
version: '0'
|
94
101
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
none: false
|
95
103
|
requirements:
|
96
104
|
- - ! '>='
|
97
105
|
- !ruby/object:Gem::Version
|
98
106
|
version: '0'
|
99
107
|
requirements: []
|
100
108
|
rubyforge_project:
|
101
|
-
rubygems_version:
|
109
|
+
rubygems_version: 1.8.23
|
102
110
|
signing_key:
|
103
|
-
specification_version:
|
111
|
+
specification_version: 3
|
104
112
|
summary: Create JSON structures via a Builder-style DSL
|
105
113
|
test_files:
|
106
114
|
- test/jbuilder_generator_test.rb
|
107
115
|
- test/jbuilder_template_test.rb
|
108
116
|
- test/jbuilder_test.rb
|
109
117
|
- test/scaffold_controller_generator_test.rb
|
110
|
-
has_rdoc:
|
checksums.yaml
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
---
|
2
|
-
!binary "U0hBMQ==":
|
3
|
-
metadata.gz: !binary |-
|
4
|
-
MmU0OWNkNDE0NGQzMWFiNmU2N2ZiOTY2NjA1MTk5ZDg3YTYyMmJiYQ==
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
N2Q5YjE3Mjk4ZThjZTU1NGQxY2QwZGQzZjJhOTliZTU3MDA2M2VmMQ==
|
7
|
-
!binary "U0hBNTEy":
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
MmYxNDMwNTAzZjI5ZDIzY2U1M2RjYjAxOTUwZDBiNzlmNjMyYTNkN2JhZWY3
|
10
|
-
OTE4NmQzMmVjZWE2YmJkYjg1NzEyNWYyYjcyMGQ1MDYxMDc1YzkxYmRlZjEw
|
11
|
-
ZDQwZDdhZjViYWQ2YmZkNDhiNTI1YzYwYjc3YjQ0NWE5ZTIyOTQ=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
NDg5NmI2ZjhiN2UyYjU4MjhhZGRiNGYzZDU4ZjBkOWQ5NTVmYzhjYjQwZmIy
|
14
|
-
MzYxZmMzMWJmMTdkMjM2YzdhNjk0ZGJjMGNmMTBhYWQ5MDI3M2VlODczNWQ3
|
15
|
-
ODE2MWQzOWU5NTZkYjI0MmRhNTk2MDk5YTUyOWZkYzgwYzRjYWQ=
|