jbuilder 2.11.0 → 2.14.1
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 +4 -4
- data/.devcontainer/devcontainer.json +25 -0
- data/.github/workflows/ruby.yml +56 -0
- data/.gitignore +1 -0
- data/Appraisals +14 -13
- data/CONTRIBUTING.md +4 -10
- data/Gemfile +2 -0
- data/README.md +113 -26
- data/Rakefile +3 -1
- data/bin/release +14 -0
- data/bin/test +6 -0
- data/gemfiles/{rails_5_1.gemfile → rails_7_0.gemfile} +2 -1
- data/gemfiles/{rails_5_2.gemfile → rails_7_1.gemfile} +1 -1
- data/gemfiles/{rails_6_0.gemfile → rails_7_2.gemfile} +1 -1
- data/gemfiles/{rails_5_0.gemfile → rails_8_0.gemfile} +1 -1
- data/gemfiles/rails_head.gemfile +1 -1
- data/jbuilder.gemspec +16 -3
- data/lib/generators/rails/jbuilder_generator.rb +6 -0
- data/lib/generators/rails/scaffold_controller_generator.rb +2 -0
- data/lib/generators/rails/templates/api_controller.rb +7 -1
- data/lib/generators/rails/templates/controller.rb +16 -14
- data/lib/generators/rails/templates/index.json.jbuilder +1 -1
- data/lib/generators/rails/templates/show.json.jbuilder +1 -1
- data/lib/jbuilder/blank.rb +2 -0
- data/lib/jbuilder/collection_renderer.rb +58 -0
- data/lib/jbuilder/errors.rb +3 -1
- data/lib/jbuilder/jbuilder.rb +3 -7
- data/lib/jbuilder/jbuilder_dependency_tracker.rb +75 -0
- data/lib/jbuilder/jbuilder_template.rb +81 -47
- data/lib/jbuilder/key_formatter.rb +19 -21
- data/lib/jbuilder/railtie.rb +17 -19
- data/lib/jbuilder/version.rb +5 -0
- data/lib/jbuilder.rb +84 -50
- data/test/jbuilder_dependency_tracker_test.rb +2 -3
- data/test/jbuilder_generator_test.rb +19 -9
- data/test/jbuilder_template_test.rb +133 -8
- data/test/jbuilder_test.rb +152 -14
- data/test/scaffold_api_controller_generator_test.rb +52 -47
- data/test/scaffold_controller_generator_test.rb +38 -12
- data/test/test_helper.rb +23 -10
- metadata +37 -18
- data/.travis.yml +0 -52
- data/CHANGELOG.md +0 -300
- data/lib/jbuilder/dependency_tracker.rb +0 -61
|
@@ -4,16 +4,14 @@ require_dependency "<%= namespaced_path %>/application_controller"
|
|
|
4
4
|
<% end -%>
|
|
5
5
|
<% module_namespacing do -%>
|
|
6
6
|
class <%= controller_class_name %>Controller < ApplicationController
|
|
7
|
-
before_action :set_<%= singular_table_name %>, only: %
|
|
7
|
+
before_action :set_<%= singular_table_name %>, only: %i[ show edit update destroy ]
|
|
8
8
|
|
|
9
|
-
# GET <%= route_url %>
|
|
10
|
-
# GET <%= route_url %>.json
|
|
9
|
+
# GET <%= route_url %> or <%= route_url %>.json
|
|
11
10
|
def index
|
|
12
11
|
@<%= plural_table_name %> = <%= orm_class.all(class_name) %>
|
|
13
12
|
end
|
|
14
13
|
|
|
15
|
-
# GET <%= route_url %>/1
|
|
16
|
-
# GET <%= route_url %>/1.json
|
|
14
|
+
# GET <%= route_url %>/1 or <%= route_url %>/1.json
|
|
17
15
|
def show
|
|
18
16
|
end
|
|
19
17
|
|
|
@@ -26,14 +24,13 @@ class <%= controller_class_name %>Controller < ApplicationController
|
|
|
26
24
|
def edit
|
|
27
25
|
end
|
|
28
26
|
|
|
29
|
-
# POST <%= route_url %>
|
|
30
|
-
# POST <%= route_url %>.json
|
|
27
|
+
# POST <%= route_url %> or <%= route_url %>.json
|
|
31
28
|
def create
|
|
32
29
|
@<%= singular_table_name %> = <%= orm_class.build(class_name, "#{singular_table_name}_params") %>
|
|
33
30
|
|
|
34
31
|
respond_to do |format|
|
|
35
32
|
if @<%= orm_instance.save %>
|
|
36
|
-
format.html { redirect_to
|
|
33
|
+
format.html { redirect_to <%= redirect_resource_name %>, notice: <%= %("#{human_name} was successfully created.") %> }
|
|
37
34
|
format.json { render :show, status: :created, location: <%= "@#{singular_table_name}" %> }
|
|
38
35
|
else
|
|
39
36
|
format.html { render :new, status: :unprocessable_entity }
|
|
@@ -42,12 +39,11 @@ class <%= controller_class_name %>Controller < ApplicationController
|
|
|
42
39
|
end
|
|
43
40
|
end
|
|
44
41
|
|
|
45
|
-
# PATCH/PUT <%= route_url %>/1
|
|
46
|
-
# PATCH/PUT <%= route_url %>/1.json
|
|
42
|
+
# PATCH/PUT <%= route_url %>/1 or <%= route_url %>/1.json
|
|
47
43
|
def update
|
|
48
44
|
respond_to do |format|
|
|
49
45
|
if @<%= orm_instance.update("#{singular_table_name}_params") %>
|
|
50
|
-
format.html { redirect_to
|
|
46
|
+
format.html { redirect_to <%= redirect_resource_name %>, notice: <%= %("#{human_name} was successfully updated.") %>, status: :see_other }
|
|
51
47
|
format.json { render :show, status: :ok, location: <%= "@#{singular_table_name}" %> }
|
|
52
48
|
else
|
|
53
49
|
format.html { render :edit, status: :unprocessable_entity }
|
|
@@ -56,12 +52,12 @@ class <%= controller_class_name %>Controller < ApplicationController
|
|
|
56
52
|
end
|
|
57
53
|
end
|
|
58
54
|
|
|
59
|
-
# DELETE <%= route_url %>/1
|
|
60
|
-
# DELETE <%= route_url %>/1.json
|
|
55
|
+
# DELETE <%= route_url %>/1 or <%= route_url %>/1.json
|
|
61
56
|
def destroy
|
|
62
57
|
@<%= orm_instance.destroy %>
|
|
58
|
+
|
|
63
59
|
respond_to do |format|
|
|
64
|
-
format.html { redirect_to <%= index_helper %>
|
|
60
|
+
format.html { redirect_to <%= index_helper %>_path, notice: <%= %("#{human_name} was successfully destroyed.") %>, status: :see_other }
|
|
65
61
|
format.json { head :no_content }
|
|
66
62
|
end
|
|
67
63
|
end
|
|
@@ -69,13 +65,19 @@ class <%= controller_class_name %>Controller < ApplicationController
|
|
|
69
65
|
private
|
|
70
66
|
# Use callbacks to share common setup or constraints between actions.
|
|
71
67
|
def set_<%= singular_table_name %>
|
|
68
|
+
<%- if Rails::VERSION::MAJOR >= 8 -%>
|
|
69
|
+
@<%= singular_table_name %> = <%= orm_class.find(class_name, "params.expect(:id)") %>
|
|
70
|
+
<%- else -%>
|
|
72
71
|
@<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
|
|
72
|
+
<%- end -%>
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
# Only allow a list of trusted parameters through.
|
|
76
76
|
def <%= "#{singular_table_name}_params" %>
|
|
77
77
|
<%- if attributes_names.empty? -%>
|
|
78
78
|
params.fetch(<%= ":#{singular_table_name}" %>, {})
|
|
79
|
+
<%- elsif Rails::VERSION::MAJOR >= 8 -%>
|
|
80
|
+
params.expect(<%= singular_table_name %>: [ <%= permitted_params %> ])
|
|
79
81
|
<%- else -%>
|
|
80
82
|
params.require(<%= ":#{singular_table_name}" %>).permit(<%= permitted_params %>)
|
|
81
83
|
<%- end -%>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
json.array! @<%= plural_table_name %>, partial: "<%=
|
|
1
|
+
json.array! @<%= plural_table_name %>, partial: "<%= partial_path_name %>", as: :<%= singular_table_name %>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
json.partial! "<%=
|
|
1
|
+
json.partial! "<%= partial_path_name %>", <%= singular_table_name %>: @<%= singular_table_name %>
|
data/lib/jbuilder/blank.rb
CHANGED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'delegate'
|
|
4
|
+
require 'action_view'
|
|
5
|
+
require 'action_view/renderer/collection_renderer'
|
|
6
|
+
|
|
7
|
+
class Jbuilder
|
|
8
|
+
class CollectionRenderer < ::ActionView::CollectionRenderer # :nodoc:
|
|
9
|
+
class ScopedIterator < ::SimpleDelegator # :nodoc:
|
|
10
|
+
include Enumerable
|
|
11
|
+
|
|
12
|
+
def initialize(obj, scope)
|
|
13
|
+
super(obj)
|
|
14
|
+
@scope = scope
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def each_with_info
|
|
18
|
+
return enum_for(:each_with_info) unless block_given?
|
|
19
|
+
|
|
20
|
+
__getobj__.each_with_info do |object, info|
|
|
21
|
+
@scope.call { yield(object, info) }
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private_constant :ScopedIterator
|
|
27
|
+
|
|
28
|
+
def initialize(lookup_context, options, &scope)
|
|
29
|
+
super(lookup_context, options)
|
|
30
|
+
@scope = scope
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def build_rendered_template(content, template, layout = nil)
|
|
36
|
+
super(content || json.attributes!, template)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def build_rendered_collection(templates, _spacer)
|
|
40
|
+
json.merge!(templates.map(&:body))
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def json
|
|
44
|
+
@options[:locals].fetch(:json)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def collection_with_template(view, template, layout, collection)
|
|
48
|
+
super(view, template, layout, ScopedIterator.new(collection, @scope))
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
class EnumerableCompat < ::SimpleDelegator
|
|
53
|
+
# Rails 6.1 requires this.
|
|
54
|
+
def size(*args, &block)
|
|
55
|
+
__getobj__.count(*args, &block)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
data/lib/jbuilder/errors.rb
CHANGED
data/lib/jbuilder/jbuilder.rb
CHANGED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Jbuilder::DependencyTracker
|
|
4
|
+
EXPLICIT_DEPENDENCY = /# Template Dependency: (\S+)/
|
|
5
|
+
|
|
6
|
+
# Matches:
|
|
7
|
+
# json.partial! "messages/message"
|
|
8
|
+
# json.partial!('messages/message')
|
|
9
|
+
#
|
|
10
|
+
DIRECT_RENDERS = /
|
|
11
|
+
\w+\.partial! # json.partial!
|
|
12
|
+
\(?\s* # optional parenthesis
|
|
13
|
+
(['"])([^'"]+)\1 # quoted value
|
|
14
|
+
/x
|
|
15
|
+
|
|
16
|
+
# Matches:
|
|
17
|
+
# json.partial! partial: "comments/comment"
|
|
18
|
+
# json.comments @post.comments, partial: "comments/comment", as: :comment
|
|
19
|
+
# json.array! @posts, partial: "posts/post", as: :post
|
|
20
|
+
# = render partial: "account"
|
|
21
|
+
#
|
|
22
|
+
INDIRECT_RENDERS = /
|
|
23
|
+
(?::partial\s*=>|partial:) # partial: or :partial =>
|
|
24
|
+
\s* # optional whitespace
|
|
25
|
+
(['"])([^'"]+)\1 # quoted value
|
|
26
|
+
/x
|
|
27
|
+
|
|
28
|
+
def self.call(name, template, view_paths = nil)
|
|
29
|
+
new(name, template, view_paths).dependencies
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def initialize(name, template, view_paths = nil)
|
|
33
|
+
@name, @template, @view_paths = name, template, view_paths
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def dependencies
|
|
37
|
+
direct_dependencies + indirect_dependencies + explicit_dependencies
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
attr_reader :name, :template
|
|
43
|
+
|
|
44
|
+
def direct_dependencies
|
|
45
|
+
source.scan(DIRECT_RENDERS).map(&:second)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def indirect_dependencies
|
|
49
|
+
source.scan(INDIRECT_RENDERS).map(&:second)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def explicit_dependencies
|
|
53
|
+
dependencies = source.scan(EXPLICIT_DEPENDENCY).flatten.uniq
|
|
54
|
+
|
|
55
|
+
wildcards, explicits = dependencies.partition { |dependency| dependency.end_with?("/*") }
|
|
56
|
+
|
|
57
|
+
(explicits + resolve_directories(wildcards)).uniq
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def resolve_directories(wildcard_dependencies)
|
|
61
|
+
return [] unless @view_paths
|
|
62
|
+
return [] if wildcard_dependencies.empty?
|
|
63
|
+
|
|
64
|
+
# Remove trailing "/*"
|
|
65
|
+
prefixes = wildcard_dependencies.map { |query| query[0..-3] }
|
|
66
|
+
|
|
67
|
+
@view_paths.flat_map(&:all_template_paths).uniq.filter_map { |path|
|
|
68
|
+
path.to_s if prefixes.include?(path.prefix)
|
|
69
|
+
}.sort
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def source
|
|
73
|
+
template.source
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'jbuilder/jbuilder'
|
|
4
|
+
require 'jbuilder/collection_renderer'
|
|
2
5
|
require 'action_dispatch/http/mime_type'
|
|
3
6
|
require 'active_support/cache'
|
|
4
7
|
|
|
@@ -9,17 +12,52 @@ class JbuilderTemplate < Jbuilder
|
|
|
9
12
|
|
|
10
13
|
self.template_lookup_options = { handlers: [:jbuilder] }
|
|
11
14
|
|
|
12
|
-
def initialize(context,
|
|
15
|
+
def initialize(context, options = nil)
|
|
13
16
|
@context = context
|
|
14
17
|
@cached_root = nil
|
|
15
|
-
|
|
18
|
+
|
|
19
|
+
options.nil? ? super() : super(**options)
|
|
16
20
|
end
|
|
17
21
|
|
|
22
|
+
# Generates JSON using the template specified with the `:partial` option. For example, the code below will render
|
|
23
|
+
# the file `views/comments/_comments.json.jbuilder`, and set a local variable comments with all this message's
|
|
24
|
+
# comments, which can be used inside the partial.
|
|
25
|
+
#
|
|
26
|
+
# Example:
|
|
27
|
+
#
|
|
28
|
+
# json.partial! 'comments/comments', comments: @message.comments
|
|
29
|
+
#
|
|
30
|
+
# There are multiple ways to generate a collection of elements as JSON, as ilustrated below:
|
|
31
|
+
#
|
|
32
|
+
# Example:
|
|
33
|
+
#
|
|
34
|
+
# json.array! @posts, partial: 'posts/post', as: :post
|
|
35
|
+
#
|
|
36
|
+
# # or:
|
|
37
|
+
# json.partial! 'posts/post', collection: @posts, as: :post
|
|
38
|
+
#
|
|
39
|
+
# # or:
|
|
40
|
+
# json.partial! partial: 'posts/post', collection: @posts, as: :post
|
|
41
|
+
#
|
|
42
|
+
# # or:
|
|
43
|
+
# json.comments @post.comments, partial: 'comments/comment', as: :comment
|
|
44
|
+
#
|
|
45
|
+
# Aside from that, the `:cached` options is available on Rails >= 6.0. This will cache the rendered results
|
|
46
|
+
# effectively using the multi fetch feature.
|
|
47
|
+
#
|
|
48
|
+
# Example:
|
|
49
|
+
#
|
|
50
|
+
# json.array! @posts, partial: "posts/post", as: :post, cached: true
|
|
51
|
+
#
|
|
52
|
+
# json.comments @post.comments, partial: "comments/comment", as: :comment, cached: true
|
|
53
|
+
#
|
|
18
54
|
def partial!(*args)
|
|
19
55
|
if args.one? && _is_active_model?(args.first)
|
|
20
56
|
_render_active_model_partial args.first
|
|
21
57
|
else
|
|
22
|
-
|
|
58
|
+
options = args.extract_options!.dup
|
|
59
|
+
options[:partial] = args.first if args.present?
|
|
60
|
+
_render_partial_with_options options
|
|
23
61
|
end
|
|
24
62
|
end
|
|
25
63
|
|
|
@@ -56,7 +94,7 @@ class JbuilderTemplate < Jbuilder
|
|
|
56
94
|
# # json.extra 'This will not work either, the root must be exclusive'
|
|
57
95
|
def cache_root!(key=nil, options={})
|
|
58
96
|
if @context.controller.perform_caching
|
|
59
|
-
raise "cache_root! can't be used after JSON structures have been defined" if @attributes.present?
|
|
97
|
+
::Kernel.raise "cache_root! can't be used after JSON structures have been defined" if @attributes.present?
|
|
60
98
|
|
|
61
99
|
@cached_root = _cache_fragment_for([ :root, key ], options) { yield; target! }
|
|
62
100
|
else
|
|
@@ -85,7 +123,9 @@ class JbuilderTemplate < Jbuilder
|
|
|
85
123
|
options = args.first
|
|
86
124
|
|
|
87
125
|
if args.one? && _partial_options?(options)
|
|
88
|
-
|
|
126
|
+
options = options.dup
|
|
127
|
+
options[:collection] = collection
|
|
128
|
+
_render_partial_with_options options
|
|
89
129
|
else
|
|
90
130
|
super
|
|
91
131
|
end
|
|
@@ -95,7 +135,7 @@ class JbuilderTemplate < Jbuilder
|
|
|
95
135
|
options = args.first
|
|
96
136
|
|
|
97
137
|
if args.one? && _partial_options?(options)
|
|
98
|
-
_set_inline_partial name, object, options
|
|
138
|
+
_set_inline_partial name, object, options.dup
|
|
99
139
|
else
|
|
100
140
|
super
|
|
101
141
|
end
|
|
@@ -103,20 +143,35 @@ class JbuilderTemplate < Jbuilder
|
|
|
103
143
|
|
|
104
144
|
private
|
|
105
145
|
|
|
146
|
+
alias_method :method_missing, :set!
|
|
147
|
+
|
|
106
148
|
def _render_partial_with_options(options)
|
|
107
|
-
options
|
|
108
|
-
options
|
|
149
|
+
options[:locals] ||= options.except(:partial, :as, :collection, :cached)
|
|
150
|
+
options[:handlers] ||= ::JbuilderTemplate.template_lookup_options[:handlers]
|
|
109
151
|
as = options[:as]
|
|
110
152
|
|
|
111
153
|
if as && options.key?(:collection)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
locals =
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
154
|
+
collection = options.delete(:collection) || []
|
|
155
|
+
partial = options.delete(:partial)
|
|
156
|
+
options[:locals][:json] = self
|
|
157
|
+
collection = EnumerableCompat.new(collection) if collection.respond_to?(:count) && !collection.respond_to?(:size)
|
|
158
|
+
|
|
159
|
+
if options.has_key?(:layout)
|
|
160
|
+
::Kernel.raise ::NotImplementedError, "The `:layout' option is not supported in collection rendering."
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
if options.has_key?(:spacer_template)
|
|
164
|
+
::Kernel.raise ::NotImplementedError, "The `:spacer_template' option is not supported in collection rendering."
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
if collection.present?
|
|
168
|
+
results = CollectionRenderer
|
|
169
|
+
.new(@context.lookup_context, options) { |&block| _scope(&block) }
|
|
170
|
+
.render_collection_with_partial(collection, partial, @context, nil)
|
|
171
|
+
|
|
172
|
+
array! if results.respond_to?(:body) && results.body.nil?
|
|
173
|
+
else
|
|
174
|
+
array!
|
|
120
175
|
end
|
|
121
176
|
else
|
|
122
177
|
_render_partial options
|
|
@@ -124,7 +179,7 @@ class JbuilderTemplate < Jbuilder
|
|
|
124
179
|
end
|
|
125
180
|
|
|
126
181
|
def _render_partial(options)
|
|
127
|
-
options[:locals]
|
|
182
|
+
options[:locals][:json] = self
|
|
128
183
|
@context.render options
|
|
129
184
|
end
|
|
130
185
|
|
|
@@ -162,12 +217,7 @@ class JbuilderTemplate < Jbuilder
|
|
|
162
217
|
|
|
163
218
|
def _fragment_name_with_digest(key, options)
|
|
164
219
|
if @context.respond_to?(:cache_fragment_name)
|
|
165
|
-
# Current compatibility, fragment_name_with_digest is private again and cache_fragment_name
|
|
166
|
-
# should be used instead.
|
|
167
220
|
@context.cache_fragment_name(key, **options)
|
|
168
|
-
elsif @context.respond_to?(:fragment_name_with_digest)
|
|
169
|
-
# Backwards compatibility for period of time when fragment_name_with_digest was made public.
|
|
170
|
-
@context.fragment_name_with_digest(key)
|
|
171
221
|
else
|
|
172
222
|
key
|
|
173
223
|
end
|
|
@@ -185,34 +235,18 @@ class JbuilderTemplate < Jbuilder
|
|
|
185
235
|
value = if object.nil?
|
|
186
236
|
[]
|
|
187
237
|
elsif _is_collection?(object)
|
|
188
|
-
_scope
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
set! name, value
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
def _render_explicit_partial(name_or_options, locals = {})
|
|
198
|
-
case name_or_options
|
|
199
|
-
when ::Hash
|
|
200
|
-
# partial! partial: 'name', foo: 'bar'
|
|
201
|
-
options = name_or_options
|
|
238
|
+
_scope do
|
|
239
|
+
options[:collection] = object
|
|
240
|
+
_render_partial_with_options options
|
|
241
|
+
end
|
|
202
242
|
else
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
options
|
|
206
|
-
else
|
|
207
|
-
options = { partial: name_or_options, locals: locals }
|
|
243
|
+
_scope do
|
|
244
|
+
options[:locals] = { options[:as] => object }
|
|
245
|
+
_render_partial_with_options options
|
|
208
246
|
end
|
|
209
|
-
# partial! 'name', foo: 'bar'
|
|
210
|
-
as = locals.delete(:as)
|
|
211
|
-
options[:as] = as if as.present?
|
|
212
|
-
options[:collection] = locals[:collection] if locals.key?(:collection)
|
|
213
247
|
end
|
|
214
248
|
|
|
215
|
-
|
|
249
|
+
_set_value name, value
|
|
216
250
|
end
|
|
217
251
|
|
|
218
252
|
def _render_active_model_partial(object)
|
|
@@ -227,7 +261,7 @@ class JbuilderHandler
|
|
|
227
261
|
def self.call(template, source = nil)
|
|
228
262
|
source ||= template.source
|
|
229
263
|
# this juggling is required to keep line numbers right in the error
|
|
230
|
-
%{__already_defined = defined?(json); json||=JbuilderTemplate.new(self); #{source}
|
|
264
|
+
%{__already_defined = defined?(json); json||=JbuilderTemplate.new(self); #{source};
|
|
231
265
|
json.target! unless (__already_defined && __already_defined != "method")}
|
|
232
266
|
end
|
|
233
267
|
end
|
|
@@ -1,32 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'jbuilder/jbuilder'
|
|
2
|
-
require 'active_support/core_ext/array'
|
|
3
4
|
|
|
4
5
|
class Jbuilder
|
|
5
6
|
class KeyFormatter
|
|
6
|
-
def initialize(*
|
|
7
|
-
@
|
|
8
|
-
@
|
|
9
|
-
|
|
10
|
-
options = args.extract_options!
|
|
11
|
-
args.each do |name|
|
|
12
|
-
@format[name] = []
|
|
13
|
-
end
|
|
14
|
-
options.each do |name, parameters|
|
|
15
|
-
@format[name] = parameters
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def initialize_copy(original)
|
|
7
|
+
def initialize(*formats, **formats_with_options)
|
|
8
|
+
@mutex = Mutex.new
|
|
9
|
+
@formats = formats
|
|
10
|
+
@formats_with_options = formats_with_options
|
|
20
11
|
@cache = {}
|
|
21
12
|
end
|
|
22
13
|
|
|
23
14
|
def format(key)
|
|
24
|
-
@
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
15
|
+
@mutex.synchronize do
|
|
16
|
+
@cache[key] ||= begin
|
|
17
|
+
value = key.is_a?(Symbol) ? key.name : key.to_s
|
|
18
|
+
|
|
19
|
+
@formats.each do |func|
|
|
20
|
+
value = func.is_a?(Proc) ? func.call(value) : value.send(func)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
@formats_with_options.each do |func, params|
|
|
24
|
+
value = func.is_a?(Proc) ? func.call(value, *params) : value.send(func, *params)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
value
|
|
30
28
|
end
|
|
31
29
|
end
|
|
32
30
|
end
|
data/lib/jbuilder/railtie.rb
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails'
|
|
2
4
|
require 'jbuilder/jbuilder_template'
|
|
3
5
|
|
|
4
6
|
class Jbuilder
|
|
@@ -6,31 +8,27 @@ class Jbuilder
|
|
|
6
8
|
initializer :jbuilder do
|
|
7
9
|
ActiveSupport.on_load :action_view do
|
|
8
10
|
ActionView::Template.register_template_handler :jbuilder, JbuilderHandler
|
|
9
|
-
require 'jbuilder/
|
|
11
|
+
require 'jbuilder/jbuilder_dependency_tracker'
|
|
10
12
|
end
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
module
|
|
14
|
-
|
|
15
|
-
include ActionView::Rendering
|
|
16
|
-
end
|
|
14
|
+
module ::ActionController
|
|
15
|
+
module ApiRendering
|
|
16
|
+
include ActionView::Rendering
|
|
17
17
|
end
|
|
18
|
+
end
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
end
|
|
20
|
+
ActiveSupport.on_load :action_controller_api do
|
|
21
|
+
include ActionController::Helpers
|
|
22
|
+
include ActionController::ImplicitRender
|
|
23
|
+
helper_method :combined_fragment_cache_key
|
|
24
|
+
helper_method :view_cache_dependencies
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
require 'generators/rails/scaffold_controller_generator'
|
|
33
|
-
end
|
|
28
|
+
generators do |app|
|
|
29
|
+
Rails::Generators.configure! app.config.generators
|
|
30
|
+
Rails::Generators.hidden_namespaces.uniq!
|
|
31
|
+
require 'generators/rails/scaffold_controller_generator'
|
|
34
32
|
end
|
|
35
33
|
end
|
|
36
34
|
end
|