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 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, "David"
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("Doodle Corp", Person.new("John Stobs", 58))
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! "api/comments/comments", comments: @message.comments
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 "David"
160
+ json.first_name 'David'
137
161
 
138
162
  # => { "firstName": "David" }
139
163
  ```
data/jbuilder.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'jbuilder'
3
- s.version = '1.3.0'
3
+ s.version = '1.4.0'
4
4
  s.author = 'David Heinemeier Hansson'
5
5
  s.email = 'david@37signals.com'
6
6
  s.summary = 'Create JSON structures via a Builder-style DSL'
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 ::Kernel.block_given?
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 ::Kernel.block_given?
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 ::Kernel::block_given?
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(:formats => [:json]))
12
+ @context.render(options.reverse_merge(:handlers => [:jbuilder]))
13
13
  else # String
14
- @context.render(:partial => options, :locals => locals.merge(:json => self), :formats => [:json])
14
+ @context.render(:partial => options, :locals => locals.merge(:json => self), :handlers => [:jbuilder])
15
15
  end
16
16
  end
17
17
 
@@ -325,8 +325,9 @@ class JbuilderTest < ActiveSupport::TestCase
325
325
  end
326
326
  end
327
327
 
328
- assert_equal 'David', MultiJson.load(json)[0]['names'].last
329
- assert_not_equal 'hello', MultiJson.load(json)[0]['not_in_json']
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
- version: 1.3.0
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-11 00:00:00.000000000 Z
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
- version_requirements: !ruby/object:Gem::Requirement
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
- requirement: !ruby/object:Gem::Requirement
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
- version_requirements: !ruby/object:Gem::Requirement
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
- requirement: !ruby/object:Gem::Requirement
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
- version_requirements: !ruby/object:Gem::Requirement
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
- requirement: !ruby/object:Gem::Requirement
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: 2.0.3
109
+ rubygems_version: 1.8.23
102
110
  signing_key:
103
- specification_version: 4
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=