jbuilder 1.4.2 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/.travis.yml +8 -3
- data/Gemfile.edge +3 -6
- data/README.md +23 -5
- data/jbuilder.gemspec +1 -1
- data/lib/jbuilder.rb +18 -2
- data/lib/jbuilder/jbuilder_template.rb +50 -12
- data/test/jbuilder_template_test.rb +63 -1
- data/test/jbuilder_test.rb +24 -5
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NGYyYTk2NWM1ZjkxN2Q1YWYxNmM1MWI2YWZhZWFlODY4YWJiNjZjYw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZGM3Mjg1NGYxODFjNGU4NGYwZWRkYmNkNTZmMjJjMmFjMzk3NTUxZA==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
OGFkMmYzYWM0MjQ5OWM5ZmU4ZjU1ODBhZmVkMzQ3ZjRjNjg0YmE2N2VmY2Rm
|
10
|
+
M2YyNDIwY2FlZTNhMzBmNDk4MDljNGMxNWVkNzMwYTMyOTRiYTEwYzE2Mjc4
|
11
|
+
NjE0ODZlZTU2MjczZjgxMDg5ZTVmZmIxZWQ0OGQ1NTI5M2FhNmQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ODc3OGEwYTkxMGFlNTdhODdmOGEzYWM1YzZiYTEyOTk5MjFmZjM4M2I5ZTU1
|
14
|
+
ZTU4Y2ViYTFhMTA1NzFmZGFlMTc5OTljYTk1OTA2MTk0MDVmOTVhZGYyMzZl
|
15
|
+
Y2Y1ZTlmOWU0OTQ2NTY1MmY1ODQ2YmY2YjdiYTEwYTA2NTYwYmE=
|
data/.travis.yml
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
language: ruby
|
2
|
-
|
3
|
-
- gem install bundler
|
2
|
+
|
4
3
|
rvm:
|
5
4
|
- 1.8.7
|
6
5
|
- 1.9.2
|
@@ -12,12 +11,14 @@ rvm:
|
|
12
11
|
- jruby-19mode
|
13
12
|
- rbx-18mode
|
14
13
|
- rbx-19mode
|
14
|
+
|
15
15
|
gemfile:
|
16
16
|
- Gemfile
|
17
17
|
- Gemfile.edge
|
18
|
+
|
18
19
|
matrix:
|
19
20
|
exclude:
|
20
|
-
# Edge Rails is only compatible with 1.9.3
|
21
|
+
# Edge Rails is only compatible with 1.9.3+
|
21
22
|
- gemfile: Gemfile.edge
|
22
23
|
rvm: 1.8.7
|
23
24
|
- gemfile: Gemfile.edge
|
@@ -28,6 +29,10 @@ matrix:
|
|
28
29
|
rvm: jruby-18mode
|
29
30
|
- gemfile: Gemfile.edge
|
30
31
|
rvm: rbx-18mode
|
32
|
+
allow_failures:
|
33
|
+
- rvm: ruby-head
|
34
|
+
- rvm: rbx-18mode
|
35
|
+
- rvm: rbx-19mode
|
31
36
|
|
32
37
|
notifications:
|
33
38
|
email: false
|
data/Gemfile.edge
CHANGED
@@ -3,9 +3,6 @@ source 'https://rubygems.org'
|
|
3
3
|
gemspec
|
4
4
|
|
5
5
|
gem 'rake'
|
6
|
-
gem '
|
7
|
-
|
8
|
-
|
9
|
-
gem 'railties', require: 'rails/railtie'
|
10
|
-
gem 'actionpack'
|
11
|
-
end
|
6
|
+
gem 'railties', '~> 4.0.0'
|
7
|
+
gem 'actionpack', '~> 4.0.0'
|
8
|
+
gem 'mocha', require: false
|
data/README.md
CHANGED
@@ -131,12 +131,30 @@ end
|
|
131
131
|
if current_user.admin?
|
132
132
|
json.visitors calculate_visitors(@message)
|
133
133
|
end
|
134
|
+
```
|
135
|
+
|
136
|
+
|
137
|
+
You can use partials as well. The following will render the file
|
138
|
+
`views/comments/_comments.json.jbuilder`, and set a local variable
|
139
|
+
`comments` with all this message's comments, which you can use inside
|
140
|
+
the partial.
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
json.partial! 'comments/comments', comments: @message.comments
|
144
|
+
```
|
145
|
+
|
146
|
+
It's also possible to render collections of partials:
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
json.array! @posts, partial: 'posts/post', as: :post
|
150
|
+
|
151
|
+
# or
|
152
|
+
|
153
|
+
json.partial! 'posts/post', collection: @posts, as: :post
|
154
|
+
|
155
|
+
# or
|
134
156
|
|
135
|
-
|
136
|
-
# RAILS_ROOT/app/views/api/comments/_comments.json.jbuilder, and set a local variable
|
137
|
-
# 'comments' with all this message's comments, which you can use inside
|
138
|
-
# the partial.
|
139
|
-
json.partial! 'api/comments/comments', comments: @message.comments
|
157
|
+
json.partial! partial: 'posts/post', collection: @posts, as: :post
|
140
158
|
```
|
141
159
|
|
142
160
|
You can explicitly make Jbuilder object return null if you want:
|
data/jbuilder.gemspec
CHANGED
data/lib/jbuilder.rb
CHANGED
@@ -252,9 +252,9 @@ class Jbuilder < JbuilderProxy
|
|
252
252
|
# json.(@person, :name, :age)
|
253
253
|
def extract!(object, *attributes)
|
254
254
|
if ::Hash === object
|
255
|
-
|
255
|
+
_extract_hash_values(object, *attributes)
|
256
256
|
else
|
257
|
-
|
257
|
+
_extract_method_values(object, *attributes)
|
258
258
|
end
|
259
259
|
end
|
260
260
|
|
@@ -285,6 +285,22 @@ class Jbuilder < JbuilderProxy
|
|
285
285
|
|
286
286
|
private
|
287
287
|
|
288
|
+
def _extract_hash_values(object, *attributes)
|
289
|
+
attributes.each{ |key| _set_value key, object.fetch(key) }
|
290
|
+
end
|
291
|
+
|
292
|
+
def _extract_method_values(object, *attributes)
|
293
|
+
attributes.each do |method_name|
|
294
|
+
unless object.respond_to?(method_name)
|
295
|
+
message = "Private method #{method_name.inspect} was used to " +
|
296
|
+
'extract value. This will be an error in future versions of Jbuilder'
|
297
|
+
end
|
298
|
+
|
299
|
+
_set_value method_name, object.send(method_name)
|
300
|
+
::ActiveSupport::Deprecation.warn message if message
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
288
304
|
def _set_value(key, value)
|
289
305
|
raise NullError, key if @attributes.nil?
|
290
306
|
unless @ignore_nil && value.nil?
|
@@ -6,14 +6,29 @@ class JbuilderTemplate < Jbuilder
|
|
6
6
|
super(*args, &block)
|
7
7
|
end
|
8
8
|
|
9
|
-
def partial!(
|
10
|
-
case
|
9
|
+
def partial!(name_or_options, locals = {})
|
10
|
+
case name_or_options
|
11
11
|
when ::Hash
|
12
|
-
|
13
|
-
options
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
# partial! partial: 'name', locals: { foo: 'bar' }
|
13
|
+
options = name_or_options
|
14
|
+
else
|
15
|
+
# partial! 'name', foo: 'bar'
|
16
|
+
options = { :partial => name_or_options, :locals => locals }
|
17
|
+
as = locals.delete(:as)
|
18
|
+
options[:as] = as if as.present?
|
19
|
+
options[:collection] = locals[:collection]
|
20
|
+
end
|
21
|
+
|
22
|
+
_handle_partial_options options
|
23
|
+
end
|
24
|
+
|
25
|
+
def array!(collection, *attributes, &block)
|
26
|
+
options = attributes.extract_options!
|
27
|
+
|
28
|
+
if options.key?(:partial)
|
29
|
+
partial! options[:partial], options.merge(:collection => collection)
|
30
|
+
else
|
31
|
+
super
|
17
32
|
end
|
18
33
|
end
|
19
34
|
|
@@ -26,15 +41,38 @@ class JbuilderTemplate < Jbuilder
|
|
26
41
|
# json.extract! @person, :name, :age
|
27
42
|
# end
|
28
43
|
def cache!(key=nil, options={}, &block)
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
44
|
+
if @context.controller.perform_caching
|
45
|
+
value = ::Rails.cache.fetch(_cache_key(key), options) do
|
46
|
+
_scope { yield self }
|
47
|
+
end
|
33
48
|
|
34
|
-
|
49
|
+
_merge(value)
|
50
|
+
else
|
51
|
+
yield
|
52
|
+
end
|
35
53
|
end
|
36
54
|
|
37
55
|
protected
|
56
|
+
def _handle_partial_options(options)
|
57
|
+
options.reverse_merge!(:locals => {}, :handlers => [:jbuilder])
|
58
|
+
collection = options.delete(:collection)
|
59
|
+
as = options[:as]
|
60
|
+
|
61
|
+
if collection && as
|
62
|
+
array!(collection) do |member|
|
63
|
+
options[:locals].merge!(as => member, :collection => collection)
|
64
|
+
_render_partial options
|
65
|
+
end
|
66
|
+
else
|
67
|
+
_render_partial options
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def _render_partial(options)
|
72
|
+
options[:locals].merge!(:json => self)
|
73
|
+
@context.render options
|
74
|
+
end
|
75
|
+
|
38
76
|
def _cache_key(key)
|
39
77
|
if @context.respond_to?(:cache_fragment_name)
|
40
78
|
# Current compatibility, fragment_name_with_digest is private again and cache_fragment_name
|
@@ -5,6 +5,20 @@ require 'action_view/testing/resolvers'
|
|
5
5
|
require 'active_support/cache'
|
6
6
|
require 'jbuilder'
|
7
7
|
|
8
|
+
|
9
|
+
BLOG_POST_PARTIAL = <<-JBUILDER
|
10
|
+
json.extract! blog_post, :id, :body
|
11
|
+
json.author do
|
12
|
+
name = blog_post.author_name.split(nil, 2)
|
13
|
+
json.first_name name[0]
|
14
|
+
json.last_name name[1]
|
15
|
+
end
|
16
|
+
JBUILDER
|
17
|
+
|
18
|
+
BlogPost = Struct.new(:id, :body, :author_name)
|
19
|
+
blog_authors = [ 'David Heinemeier Hansson', 'Pavel Pravosud' ].cycle
|
20
|
+
BLOG_POST_COLLECTION = 10.times.map{ |i| BlogPost.new(i+1, "post body #{i+1}", blog_authors.next) }
|
21
|
+
|
8
22
|
module Rails
|
9
23
|
def self.cache
|
10
24
|
@cache ||= ActiveSupport::Cache::MemoryStore.new
|
@@ -18,7 +32,10 @@ class JbuilderTemplateTest < ActionView::TestCase
|
|
18
32
|
end
|
19
33
|
|
20
34
|
def partials
|
21
|
-
{
|
35
|
+
{
|
36
|
+
'_partial.json.jbuilder' => 'json.content "hello"',
|
37
|
+
'_blog_post.json.jbuilder' => BLOG_POST_PARTIAL
|
38
|
+
}
|
22
39
|
end
|
23
40
|
|
24
41
|
def render_jbuilder(source)
|
@@ -35,6 +52,16 @@ class JbuilderTemplateTest < ActionView::TestCase
|
|
35
52
|
end
|
36
53
|
end
|
37
54
|
|
55
|
+
def assert_collection_rendered(json)
|
56
|
+
result = MultiJson.load(json)
|
57
|
+
|
58
|
+
assert_equal 10, result.length
|
59
|
+
assert_equal Array, result.class
|
60
|
+
assert_equal 'post body 5', result[4]['body']
|
61
|
+
assert_equal 'Heinemeier Hansson', result[2]['author']['last_name']
|
62
|
+
assert_equal 'Pavel', result[5]['author']['first_name']
|
63
|
+
end
|
64
|
+
|
38
65
|
test 'rendering' do
|
39
66
|
json = render_jbuilder <<-JBUILDER
|
40
67
|
json.content 'hello'
|
@@ -74,6 +101,30 @@ class JbuilderTemplateTest < ActionView::TestCase
|
|
74
101
|
assert_equal 'hello', MultiJson.load(json)['content']
|
75
102
|
end
|
76
103
|
|
104
|
+
test 'partial! renders collections' do
|
105
|
+
json = render_jbuilder <<-JBUILDER
|
106
|
+
json.partial! 'blog_post', :collection => BLOG_POST_COLLECTION, :as => :blog_post
|
107
|
+
JBUILDER
|
108
|
+
|
109
|
+
assert_collection_rendered json
|
110
|
+
end
|
111
|
+
|
112
|
+
test 'partial! renders collection (alt. syntax)' do
|
113
|
+
json = render_jbuilder <<-JBUILDER
|
114
|
+
json.partial! :partial => 'blog_post', :collection => BLOG_POST_COLLECTION, :as => :blog_post
|
115
|
+
JBUILDER
|
116
|
+
|
117
|
+
assert_collection_rendered json
|
118
|
+
end
|
119
|
+
|
120
|
+
test 'render array of partials' do
|
121
|
+
json = render_jbuilder <<-JBUILDER
|
122
|
+
json.array! BLOG_POST_COLLECTION, :partial => 'blog_post', :as => :blog_post
|
123
|
+
JBUILDER
|
124
|
+
|
125
|
+
assert_collection_rendered json
|
126
|
+
end
|
127
|
+
|
77
128
|
test 'fragment caching a JSON object' do
|
78
129
|
undef_context_methods :fragment_name_with_digest, :cache_fragment_name
|
79
130
|
|
@@ -136,6 +187,17 @@ class JbuilderTemplateTest < ActionView::TestCase
|
|
136
187
|
JBUILDER
|
137
188
|
end
|
138
189
|
|
190
|
+
test 'does not perform caching when controller.perform_caching is false' do
|
191
|
+
controller.perform_caching = false
|
192
|
+
render_jbuilder <<-JBUILDER
|
193
|
+
json.cache! 'cachekey' do
|
194
|
+
json.name 'Cache'
|
195
|
+
end
|
196
|
+
JBUILDER
|
197
|
+
|
198
|
+
assert_equal Rails.cache.inspect[/entries=(\d+)/, 1], '0'
|
199
|
+
end
|
200
|
+
|
139
201
|
test 'fragment caching falls back on ActiveSupport::Cache.expand_cache_key' do
|
140
202
|
undef_context_methods :fragment_name_with_digest, :cache_fragment_name
|
141
203
|
|
data/test/jbuilder_test.rb
CHANGED
@@ -5,12 +5,14 @@ require 'jbuilder'
|
|
5
5
|
|
6
6
|
Comment = Struct.new(:content, :id)
|
7
7
|
|
8
|
-
|
9
|
-
# Faking Object#instance_eval for 1.8
|
10
|
-
|
11
|
-
|
8
|
+
unless JbuilderProxy.method_defined? :instance_eval
|
9
|
+
# Faking Object#instance_eval for 1.8 and some newer JRubies
|
10
|
+
class JbuilderProxy
|
11
|
+
def instance_eval(code)
|
12
|
+
eval code
|
13
|
+
end
|
12
14
|
end
|
13
|
-
end
|
15
|
+
end
|
14
16
|
|
15
17
|
class NonEnumerable
|
16
18
|
def initialize(collection)
|
@@ -71,6 +73,23 @@ class JbuilderTest < ActiveSupport::TestCase
|
|
71
73
|
assert_equal 32, parsed['age']
|
72
74
|
end
|
73
75
|
|
76
|
+
test 'extracting from object using private method' do
|
77
|
+
person = Struct.new(:name) do
|
78
|
+
private
|
79
|
+
def age
|
80
|
+
32
|
81
|
+
end
|
82
|
+
end.new('David')
|
83
|
+
|
84
|
+
message = 'Private method :age was used to extract value. This will be' +
|
85
|
+
' an error in future versions of Jbuilder'
|
86
|
+
|
87
|
+
::ActiveSupport::Deprecation.expects(:warn).with(message)
|
88
|
+
json = Jbuilder.encode do |json|
|
89
|
+
json.extract! person, :name, :age
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
74
93
|
test 'extracting from object using call style for 1.9' do
|
75
94
|
person = Struct.new(:name, :age).new('David', 32)
|
76
95
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jbuilder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-07-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
- - ! '>='
|
17
17
|
- !ruby/object:Gem::Version
|
18
18
|
version: 3.0.0
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
name: activesupport
|
19
22
|
version_requirements: !ruby/object:Gem::Requirement
|
20
23
|
requirements:
|
21
24
|
- - ! '>='
|
22
25
|
- !ruby/object:Gem::Version
|
23
26
|
version: 3.0.0
|
24
|
-
type: :runtime
|
25
|
-
prerelease: false
|
26
|
-
name: activesupport
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 1.2.0
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
name: multi_json
|
33
36
|
version_requirements: !ruby/object:Gem::Requirement
|
34
37
|
requirements:
|
35
38
|
- - ! '>='
|
36
39
|
- !ruby/object:Gem::Version
|
37
40
|
version: 1.2.0
|
38
|
-
type: :runtime
|
39
|
-
prerelease: false
|
40
|
-
name: multi_json
|
41
41
|
description:
|
42
42
|
email: david@37signals.com
|
43
43
|
executables: []
|
@@ -84,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
84
84
|
version: '0'
|
85
85
|
requirements: []
|
86
86
|
rubyforge_project:
|
87
|
-
rubygems_version: 2.0.
|
87
|
+
rubygems_version: 2.0.6
|
88
88
|
signing_key:
|
89
89
|
specification_version: 4
|
90
90
|
summary: Create JSON structures via a Builder-style DSL
|