actionpack 7.1.5.1 → 8.1.2

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.
Files changed (177) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +308 -523
  3. data/README.rdoc +1 -1
  4. data/lib/abstract_controller/asset_paths.rb +6 -2
  5. data/lib/abstract_controller/base.rb +104 -105
  6. data/lib/abstract_controller/caching/fragments.rb +50 -53
  7. data/lib/abstract_controller/caching.rb +8 -3
  8. data/lib/abstract_controller/callbacks.rb +70 -62
  9. data/lib/abstract_controller/collector.rb +7 -7
  10. data/lib/abstract_controller/deprecator.rb +2 -0
  11. data/lib/abstract_controller/error.rb +2 -0
  12. data/lib/abstract_controller/helpers.rb +71 -84
  13. data/lib/abstract_controller/logger.rb +4 -1
  14. data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
  15. data/lib/abstract_controller/rendering.rb +13 -13
  16. data/lib/abstract_controller/translation.rb +12 -13
  17. data/lib/abstract_controller/url_for.rb +8 -6
  18. data/lib/abstract_controller.rb +2 -0
  19. data/lib/action_controller/api/api_rendering.rb +2 -0
  20. data/lib/action_controller/api.rb +76 -72
  21. data/lib/action_controller/base.rb +199 -126
  22. data/lib/action_controller/caching.rb +16 -14
  23. data/lib/action_controller/deprecator.rb +2 -0
  24. data/lib/action_controller/form_builder.rb +21 -18
  25. data/lib/action_controller/log_subscriber.rb +23 -2
  26. data/lib/action_controller/metal/allow_browser.rb +133 -0
  27. data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
  28. data/lib/action_controller/metal/conditional_get.rb +217 -175
  29. data/lib/action_controller/metal/content_security_policy.rb +25 -24
  30. data/lib/action_controller/metal/cookies.rb +4 -2
  31. data/lib/action_controller/metal/data_streaming.rb +72 -63
  32. data/lib/action_controller/metal/default_headers.rb +5 -3
  33. data/lib/action_controller/metal/etag_with_flash.rb +3 -1
  34. data/lib/action_controller/metal/etag_with_template_digest.rb +17 -15
  35. data/lib/action_controller/metal/exceptions.rb +16 -9
  36. data/lib/action_controller/metal/flash.rb +13 -14
  37. data/lib/action_controller/metal/head.rb +15 -11
  38. data/lib/action_controller/metal/helpers.rb +63 -55
  39. data/lib/action_controller/metal/http_authentication.rb +209 -201
  40. data/lib/action_controller/metal/implicit_render.rb +17 -15
  41. data/lib/action_controller/metal/instrumentation.rb +16 -14
  42. data/lib/action_controller/metal/live.rb +177 -128
  43. data/lib/action_controller/metal/logging.rb +6 -4
  44. data/lib/action_controller/metal/mime_responds.rb +151 -142
  45. data/lib/action_controller/metal/parameter_encoding.rb +34 -32
  46. data/lib/action_controller/metal/params_wrapper.rb +57 -59
  47. data/lib/action_controller/metal/permissions_policy.rb +22 -12
  48. data/lib/action_controller/metal/rate_limiting.rb +92 -0
  49. data/lib/action_controller/metal/redirecting.rb +213 -94
  50. data/lib/action_controller/metal/renderers.rb +78 -57
  51. data/lib/action_controller/metal/rendering.rb +111 -77
  52. data/lib/action_controller/metal/request_forgery_protection.rb +182 -143
  53. data/lib/action_controller/metal/rescue.rb +20 -9
  54. data/lib/action_controller/metal/streaming.rb +118 -195
  55. data/lib/action_controller/metal/strong_parameters.rb +720 -530
  56. data/lib/action_controller/metal/testing.rb +2 -0
  57. data/lib/action_controller/metal/url_for.rb +17 -15
  58. data/lib/action_controller/metal.rb +86 -60
  59. data/lib/action_controller/railtie.rb +36 -15
  60. data/lib/action_controller/railties/helpers.rb +2 -0
  61. data/lib/action_controller/renderer.rb +41 -36
  62. data/lib/action_controller/structured_event_subscriber.rb +116 -0
  63. data/lib/action_controller/template_assertions.rb +4 -2
  64. data/lib/action_controller/test_case.rb +160 -131
  65. data/lib/action_controller.rb +5 -1
  66. data/lib/action_dispatch/constants.rb +8 -0
  67. data/lib/action_dispatch/deprecator.rb +2 -0
  68. data/lib/action_dispatch/http/cache.rb +163 -35
  69. data/lib/action_dispatch/http/content_disposition.rb +2 -0
  70. data/lib/action_dispatch/http/content_security_policy.rb +54 -39
  71. data/lib/action_dispatch/http/filter_parameters.rb +14 -8
  72. data/lib/action_dispatch/http/filter_redirect.rb +22 -1
  73. data/lib/action_dispatch/http/headers.rb +22 -22
  74. data/lib/action_dispatch/http/mime_negotiation.rb +89 -41
  75. data/lib/action_dispatch/http/mime_type.rb +25 -21
  76. data/lib/action_dispatch/http/mime_types.rb +3 -0
  77. data/lib/action_dispatch/http/param_builder.rb +187 -0
  78. data/lib/action_dispatch/http/param_error.rb +26 -0
  79. data/lib/action_dispatch/http/parameters.rb +14 -12
  80. data/lib/action_dispatch/http/permissions_policy.rb +25 -36
  81. data/lib/action_dispatch/http/query_parser.rb +55 -0
  82. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  83. data/lib/action_dispatch/http/request.rb +141 -92
  84. data/lib/action_dispatch/http/response.rb +137 -77
  85. data/lib/action_dispatch/http/upload.rb +18 -16
  86. data/lib/action_dispatch/http/url.rb +187 -89
  87. data/lib/action_dispatch/journey/formatter.rb +21 -9
  88. data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
  89. data/lib/action_dispatch/journey/gtg/simulator.rb +34 -11
  90. data/lib/action_dispatch/journey/gtg/transition_table.rb +47 -53
  91. data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
  92. data/lib/action_dispatch/journey/nodes/node.rb +8 -6
  93. data/lib/action_dispatch/journey/parser.rb +99 -195
  94. data/lib/action_dispatch/journey/path/pattern.rb +4 -1
  95. data/lib/action_dispatch/journey/route.rb +54 -38
  96. data/lib/action_dispatch/journey/router/utils.rb +22 -27
  97. data/lib/action_dispatch/journey/router.rb +63 -83
  98. data/lib/action_dispatch/journey/routes.rb +11 -2
  99. data/lib/action_dispatch/journey/scanner.rb +46 -42
  100. data/lib/action_dispatch/journey/visitors.rb +57 -23
  101. data/lib/action_dispatch/journey/visualizer/fsm.js +4 -6
  102. data/lib/action_dispatch/journey.rb +2 -0
  103. data/lib/action_dispatch/log_subscriber.rb +7 -1
  104. data/lib/action_dispatch/middleware/actionable_exceptions.rb +2 -0
  105. data/lib/action_dispatch/middleware/assume_ssl.rb +8 -5
  106. data/lib/action_dispatch/middleware/callbacks.rb +3 -1
  107. data/lib/action_dispatch/middleware/cookies.rb +125 -106
  108. data/lib/action_dispatch/middleware/debug_exceptions.rb +37 -8
  109. data/lib/action_dispatch/middleware/debug_locks.rb +15 -13
  110. data/lib/action_dispatch/middleware/debug_view.rb +13 -5
  111. data/lib/action_dispatch/middleware/exception_wrapper.rb +18 -23
  112. data/lib/action_dispatch/middleware/executor.rb +19 -4
  113. data/lib/action_dispatch/middleware/flash.rb +63 -51
  114. data/lib/action_dispatch/middleware/host_authorization.rb +17 -15
  115. data/lib/action_dispatch/middleware/public_exceptions.rb +14 -12
  116. data/lib/action_dispatch/middleware/reloader.rb +5 -3
  117. data/lib/action_dispatch/middleware/remote_ip.rb +87 -77
  118. data/lib/action_dispatch/middleware/request_id.rb +16 -10
  119. data/lib/action_dispatch/middleware/server_timing.rb +4 -2
  120. data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -0
  121. data/lib/action_dispatch/middleware/session/cache_store.rb +30 -8
  122. data/lib/action_dispatch/middleware/session/cookie_store.rb +27 -26
  123. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -3
  124. data/lib/action_dispatch/middleware/show_exceptions.rb +16 -16
  125. data/lib/action_dispatch/middleware/ssl.rb +53 -40
  126. data/lib/action_dispatch/middleware/stack.rb +11 -10
  127. data/lib/action_dispatch/middleware/static.rb +33 -31
  128. data/lib/action_dispatch/middleware/templates/rescues/_copy_button.html.erb +1 -0
  129. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +3 -5
  130. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +9 -5
  131. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +1 -0
  132. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +1 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +4 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +3 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +50 -0
  136. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +1 -0
  137. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -0
  138. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -0
  139. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -0
  140. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -0
  141. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
  142. data/lib/action_dispatch/railtie.rb +23 -3
  143. data/lib/action_dispatch/request/session.rb +24 -21
  144. data/lib/action_dispatch/request/utils.rb +11 -3
  145. data/lib/action_dispatch/routing/endpoint.rb +2 -0
  146. data/lib/action_dispatch/routing/inspector.rb +85 -60
  147. data/lib/action_dispatch/routing/mapper.rb +1031 -851
  148. data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
  149. data/lib/action_dispatch/routing/redirection.rb +47 -39
  150. data/lib/action_dispatch/routing/route_set.rb +79 -56
  151. data/lib/action_dispatch/routing/routes_proxy.rb +7 -4
  152. data/lib/action_dispatch/routing/url_for.rb +130 -125
  153. data/lib/action_dispatch/routing.rb +150 -148
  154. data/lib/action_dispatch/structured_event_subscriber.rb +20 -0
  155. data/lib/action_dispatch/system_test_case.rb +91 -81
  156. data/lib/action_dispatch/system_testing/browser.rb +16 -23
  157. data/lib/action_dispatch/system_testing/driver.rb +2 -0
  158. data/lib/action_dispatch/system_testing/server.rb +2 -0
  159. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +34 -23
  160. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
  161. data/lib/action_dispatch/testing/assertion_response.rb +9 -7
  162. data/lib/action_dispatch/testing/assertions/response.rb +52 -25
  163. data/lib/action_dispatch/testing/assertions/routing.rb +168 -87
  164. data/lib/action_dispatch/testing/assertions.rb +2 -0
  165. data/lib/action_dispatch/testing/integration.rb +233 -223
  166. data/lib/action_dispatch/testing/request_encoder.rb +11 -9
  167. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  168. data/lib/action_dispatch/testing/test_process.rb +11 -8
  169. data/lib/action_dispatch/testing/test_request.rb +3 -1
  170. data/lib/action_dispatch/testing/test_response.rb +27 -26
  171. data/lib/action_dispatch.rb +36 -32
  172. data/lib/action_pack/gem_version.rb +6 -4
  173. data/lib/action_pack/version.rb +3 -1
  174. data/lib/action_pack.rb +17 -16
  175. metadata +36 -32
  176. data/lib/action_dispatch/journey/parser.y +0 -50
  177. data/lib/action_dispatch/journey/parser_extras.rb +0 -31
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "set"
3
+ # :markup: markdown
4
4
 
5
5
  module ActionController
6
6
  # See Renderers.add
@@ -13,7 +13,7 @@ module ActionController
13
13
  Renderers.remove(key)
14
14
  end
15
15
 
16
- # See <tt>Responder#api_behavior</tt>
16
+ # See `Responder#api_behavior`
17
17
  class MissingRenderer < LoadError
18
18
  def initialize(format)
19
19
  super "No renderer defined for format: #{format}"
@@ -24,11 +24,26 @@ module ActionController
24
24
  extend ActiveSupport::Concern
25
25
 
26
26
  # A Set containing renderer names that correspond to available renderer procs.
27
- # Default values are <tt>:json</tt>, <tt>:js</tt>, <tt>:xml</tt>.
27
+ # Default values are `:json`, `:js`, `:xml`.
28
28
  RENDERERS = Set.new
29
29
 
30
+ module DeprecatedEscapeJsonResponses # :nodoc:
31
+ def escape_json_responses=(value)
32
+ if value
33
+ ActionController.deprecator.warn(<<~MSG.squish)
34
+ Setting action_controller.escape_json_responses = true is deprecated and will have no effect in Rails 8.2.
35
+ Set it to `false`, or remove the config.
36
+ MSG
37
+ end
38
+ super
39
+ end
40
+ end
41
+
30
42
  included do
31
43
  class_attribute :_renderers, default: Set.new.freeze
44
+ class_attribute :escape_json_responses, instance_writer: false, instance_accessor: false, default: true
45
+
46
+ singleton_class.prepend DeprecatedEscapeJsonResponses
32
47
  end
33
48
 
34
49
  # Used in ActionController::Base and ActionController::API to include all
@@ -42,35 +57,34 @@ module ActionController
42
57
  end
43
58
  end
44
59
 
45
- # Adds a new renderer to call within controller actions.
46
- # A renderer is invoked by passing its name as an option to
47
- # AbstractController::Rendering#render. To create a renderer
48
- # pass it a name and a block. The block takes two arguments, the first
49
- # is the value paired with its key and the second is the remaining
50
- # hash of options passed to +render+.
60
+ # Adds a new renderer to call within controller actions. A renderer is invoked
61
+ # by passing its name as an option to AbstractController::Rendering#render. To
62
+ # create a renderer pass it a name and a block. The block takes two arguments,
63
+ # the first is the value paired with its key and the second is the remaining
64
+ # hash of options passed to `render`.
51
65
  #
52
66
  # Create a csv renderer:
53
67
  #
54
- # ActionController::Renderers.add :csv do |obj, options|
55
- # filename = options[:filename] || 'data'
56
- # str = obj.respond_to?(:to_csv) ? obj.to_csv : obj.to_s
57
- # send_data str, type: Mime[:csv],
58
- # disposition: "attachment; filename=#{filename}.csv"
59
- # end
68
+ # ActionController::Renderers.add :csv do |obj, options|
69
+ # filename = options[:filename] || 'data'
70
+ # str = obj.respond_to?(:to_csv) ? obj.to_csv : obj.to_s
71
+ # send_data str, type: Mime[:csv],
72
+ # disposition: "attachment; filename=#{filename}.csv"
73
+ # end
60
74
  #
61
- # Note that we used Mime[:csv] for the csv mime type as it comes with \Rails.
75
+ # Note that we used [Mime](:csv) for the csv mime type as it comes with Rails.
62
76
  # For a custom renderer, you'll need to register a mime type with
63
- # <tt>Mime::Type.register</tt>.
77
+ # `Mime::Type.register`.
64
78
  #
65
79
  # To use the csv renderer in a controller action:
66
80
  #
67
- # def show
68
- # @csvable = Csvable.find(params[:id])
69
- # respond_to do |format|
70
- # format.html
71
- # format.csv { render csv: @csvable, filename: @csvable.name }
81
+ # def show
82
+ # @csvable = Csvable.find(params[:id])
83
+ # respond_to do |format|
84
+ # format.html
85
+ # format.csv { render csv: @csvable, filename: @csvable.name }
86
+ # end
72
87
  # end
73
- # end
74
88
  def self.add(key, &block)
75
89
  define_method(_render_with_renderer_method_name(key), &block)
76
90
  RENDERERS << key.to_sym
@@ -80,51 +94,51 @@ module ActionController
80
94
  #
81
95
  # To remove a csv renderer:
82
96
  #
83
- # ActionController::Renderers.remove(:csv)
97
+ # ActionController::Renderers.remove(:csv)
84
98
  def self.remove(key)
85
99
  RENDERERS.delete(key.to_sym)
86
100
  method_name = _render_with_renderer_method_name(key)
87
101
  remove_possible_method(method_name)
88
102
  end
89
103
 
90
- def self._render_with_renderer_method_name(key)
104
+ def self._render_with_renderer_method_name(key) # :nodoc:
91
105
  "_render_with_renderer_#{key}"
92
106
  end
93
107
 
94
108
  module ClassMethods
95
- # Adds, by name, a renderer or renderers to the +_renderers+ available
96
- # to call within controller actions.
109
+ # Adds, by name, a renderer or renderers to the `_renderers` available to call
110
+ # within controller actions.
97
111
  #
98
112
  # It is useful when rendering from an ActionController::Metal controller or
99
113
  # otherwise to add an available renderer proc to a specific controller.
100
114
  #
101
- # Both ActionController::Base and ActionController::API
102
- # include ActionController::Renderers::All, making all renderers
103
- # available in the controller. See Renderers::RENDERERS and Renderers.add.
115
+ # Both ActionController::Base and ActionController::API include
116
+ # ActionController::Renderers::All, making all renderers available in the
117
+ # controller. See Renderers::RENDERERS and Renderers.add.
104
118
  #
105
- # Since ActionController::Metal controllers cannot render, the controller
106
- # must include AbstractController::Rendering, ActionController::Rendering,
107
- # and ActionController::Renderers, and have at least one renderer.
119
+ # Since ActionController::Metal controllers cannot render, the controller must
120
+ # include AbstractController::Rendering, ActionController::Rendering, and
121
+ # ActionController::Renderers, and have at least one renderer.
108
122
  #
109
- # Rather than including ActionController::Renderers::All and including all renderers,
110
- # you may specify which renderers to include by passing the renderer name or names to
111
- # +use_renderers+. For example, a controller that includes only the <tt>:json</tt> renderer
112
- # (+_render_with_renderer_json+) might look like:
123
+ # Rather than including ActionController::Renderers::All and including all
124
+ # renderers, you may specify which renderers to include by passing the renderer
125
+ # name or names to `use_renderers`. For example, a controller that includes only
126
+ # the `:json` renderer (`_render_with_renderer_json`) might look like:
113
127
  #
114
- # class MetalRenderingController < ActionController::Metal
115
- # include AbstractController::Rendering
116
- # include ActionController::Rendering
117
- # include ActionController::Renderers
128
+ # class MetalRenderingController < ActionController::Metal
129
+ # include AbstractController::Rendering
130
+ # include ActionController::Rendering
131
+ # include ActionController::Renderers
118
132
  #
119
- # use_renderers :json
133
+ # use_renderers :json
120
134
  #
121
- # def show
122
- # render json: record
135
+ # def show
136
+ # render json: record
137
+ # end
123
138
  # end
124
- # end
125
139
  #
126
- # You must specify a +use_renderer+, else the +controller.renderer+ and
127
- # +controller._renderers+ will be <tt>nil</tt>, and the action will fail.
140
+ # You must specify a `use_renderer`, else the `controller.renderer` and
141
+ # `controller._renderers` will be `nil`, and the action will fail.
128
142
  def use_renderers(*args)
129
143
  renderers = _renderers + args
130
144
  self._renderers = renderers.freeze
@@ -132,16 +146,16 @@ module ActionController
132
146
  alias use_renderer use_renderers
133
147
  end
134
148
 
135
- # Called by +render+ in AbstractController::Rendering
136
- # which sets the return value as the +response_body+.
149
+ # Called by `render` in AbstractController::Rendering which sets the return
150
+ # value as the `response_body`.
137
151
  #
138
- # If no renderer is found, +super+ returns control to
139
- # <tt>ActionView::Rendering.render_to_body</tt>, if present.
152
+ # If no renderer is found, `super` returns control to
153
+ # `ActionView::Rendering.render_to_body`, if present.
140
154
  def render_to_body(options)
141
155
  _render_to_body_with_renderer(options) || super
142
156
  end
143
157
 
144
- def _render_to_body_with_renderer(options)
158
+ def _render_to_body_with_renderer(options) # :nodoc:
145
159
  _renderers.each do |name|
146
160
  if options.key?(name)
147
161
  _process_options(options)
@@ -153,28 +167,35 @@ module ActionController
153
167
  end
154
168
 
155
169
  add :json do |json, options|
156
- json = json.to_json(options) unless json.kind_of?(String)
170
+ json_options = options.except(:callback, :content_type, :status)
171
+ json_options[:escape] ||= false if !self.class.escape_json_responses? && options[:callback].blank?
172
+ json = json.to_json(json_options) unless json.kind_of?(String)
157
173
 
158
174
  if options[:callback].present?
159
175
  if media_type.nil? || media_type == Mime[:json]
160
- self.content_type = Mime[:js]
176
+ self.content_type = :js
161
177
  end
162
178
 
163
179
  "/**/#{options[:callback]}(#{json})"
164
180
  else
165
- self.content_type = Mime[:json] if media_type.nil?
181
+ self.content_type = :json if media_type.nil?
166
182
  json
167
183
  end
168
184
  end
169
185
 
170
186
  add :js do |js, options|
171
- self.content_type = Mime[:js] if media_type.nil?
187
+ self.content_type = :js if media_type.nil?
172
188
  js.respond_to?(:to_js) ? js.to_js(options) : js
173
189
  end
174
190
 
175
191
  add :xml do |xml, options|
176
- self.content_type = Mime[:xml] if media_type.nil?
192
+ self.content_type = :xml if media_type.nil?
177
193
  xml.respond_to?(:to_xml) ? xml.to_xml(options) : xml
178
194
  end
195
+
196
+ add :markdown do |md, options|
197
+ self.content_type = :md if media_type.nil?
198
+ md.respond_to?(:to_markdown) ? md.to_markdown : md
199
+ end
179
200
  end
180
201
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionController
4
6
  module Rendering
5
7
  extend ActiveSupport::Concern
@@ -10,8 +12,8 @@ module ActionController
10
12
  # Documentation at ActionController::Renderer#render
11
13
  delegate :render, to: :renderer
12
14
 
13
- # Returns a renderer instance (inherited from ActionController::Renderer)
14
- # for the controller.
15
+ # Returns a renderer instance (inherited from ActionController::Renderer) for
16
+ # the controller.
15
17
  attr_reader :renderer
16
18
 
17
19
  def setup_renderer! # :nodoc:
@@ -24,113 +26,145 @@ module ActionController
24
26
  end
25
27
  end
26
28
 
27
- # Renders a template and assigns the result to +self.response_body+.
29
+ # Renders a template and assigns the result to `self.response_body`.
30
+ #
31
+ # If no rendering mode option is specified, the template will be derived from
32
+ # the first argument.
33
+ #
34
+ # render "posts/show"
35
+ # # => renders app/views/posts/show.html.erb
36
+ #
37
+ # # In a PostsController action...
38
+ # render :show
39
+ # # => renders app/views/posts/show.html.erb
40
+ #
41
+ # If the first argument responds to `render_in`, the template will be rendered
42
+ # by calling `render_in` with the current view context.
28
43
  #
29
- # If no rendering mode option is specified, the template will be derived
30
- # from the first argument.
44
+ # class Greeting
45
+ # def render_in(view_context)
46
+ # view_context.render html: "<h1>Hello, World</h1>"
47
+ # end
31
48
  #
32
- # render "posts/show"
33
- # # => renders app/views/posts/show.html.erb
49
+ # def format
50
+ # :html
51
+ # end
52
+ # end
34
53
  #
35
- # # In a PostsController action...
36
- # render :show
37
- # # => renders app/views/posts/show.html.erb
54
+ # render(Greeting.new)
55
+ # # => "<h1>Hello, World</h1>"
38
56
  #
39
- # If the first argument responds to +render_in+, the template will be
40
- # rendered by calling +render_in+ with the current view context.
57
+ # render(renderable: Greeting.new)
58
+ # # => "<h1>Hello, World</h1>"
41
59
  #
42
- # ==== \Rendering Mode
60
+ # #### Rendering Mode
43
61
  #
44
- # [+:partial+]
45
- # See ActionView::PartialRenderer for details.
62
+ # `:partial`
63
+ # : See ActionView::PartialRenderer for details.
46
64
  #
47
- # render partial: "posts/form", locals: { post: Post.new }
48
- # # => renders app/views/posts/_form.html.erb
65
+ # render partial: "posts/form", locals: { post: Post.new }
66
+ # # => renders app/views/posts/_form.html.erb
49
67
  #
50
- # [+:file+]
51
- # Renders the contents of a file. This option should <b>not</b> be used
52
- # with unsanitized user input.
68
+ # `:file`
69
+ # : Renders the contents of a file. This option should **not** be used with
70
+ # unsanitized user input.
53
71
  #
54
- # render file: "/path/to/some/file"
55
- # # => renders /path/to/some/file
72
+ # render file: "/path/to/some/file"
73
+ # # => renders /path/to/some/file
56
74
  #
57
- # [+:inline+]
58
- # Renders an ERB template string.
75
+ # `:inline`
76
+ # : Renders an ERB template string.
59
77
  #
60
- # @name = "World"
61
- # render inline: "<h1>Hello, <%= @name %>!</h1>"
62
- # # => renders "<h1>Hello, World!</h1>"
78
+ # @name = "World"
79
+ # render inline: "<h1>Hello, <%= @name %>!</h1>"
80
+ # # => renders "<h1>Hello, World!</h1>"
63
81
  #
64
- # [+:body+]
65
- # Renders the provided text, and sets the content type as +text/plain+.
82
+ # `:body`
83
+ # : Renders the provided text, and sets the content type as `text/plain`.
66
84
  #
67
- # render body: "Hello, World!"
68
- # # => renders "Hello, World!"
85
+ # render body: "Hello, World!"
86
+ # # => renders "Hello, World!"
69
87
  #
70
- # [+:plain+]
71
- # Renders the provided text, and sets the content type as +text/plain+.
88
+ # `:plain`
89
+ # : Renders the provided text, and sets the content type as `text/plain`.
72
90
  #
73
- # render plain: "Hello, World!"
74
- # # => renders "Hello, World!"
91
+ # render plain: "Hello, World!"
92
+ # # => renders "Hello, World!"
75
93
  #
76
- # [+:html+]
77
- # Renders the provided HTML string, and sets the content type as +text/html+.
78
- # If the string is not +html_safe?+, performs HTML escaping on the string
79
- # before rendering.
94
+ # `:html`
95
+ # : Renders the provided HTML string, and sets the content type as
96
+ # `text/html`. If the string is not `html_safe?`, performs HTML escaping on
97
+ # the string before rendering.
80
98
  #
81
- # render html: "<h1>Hello, World!</h1>".html_safe
82
- # # => renders "<h1>Hello, World!</h1>"
99
+ # render html: "<h1>Hello, World!</h1>".html_safe
100
+ # # => renders "<h1>Hello, World!</h1>"
83
101
  #
84
- # render html: "<h1>Hello, World!</h1>"
85
- # # => renders "&lt;h1&gt;Hello, World!&lt;/h1&gt;"
102
+ # render html: "<h1>Hello, World!</h1>"
103
+ # # => renders "&lt;h1&gt;Hello, World!&lt;/h1&gt;"
86
104
  #
87
- # [+:json+]
88
- # Renders the provided object as JSON, and sets the content type as
89
- # +application/json+. If the object is not a string, it will be converted
90
- # to JSON by calling +to_json+.
105
+ # `:json`
106
+ # : Renders the provided object as JSON, and sets the content type as
107
+ # `application/json`. If the object is not a string, it will be converted to
108
+ # JSON by calling `to_json`.
109
+ #
110
+ # render json: { hello: "world" }
111
+ # # => renders "{\"hello\":\"world\"}"
112
+ #
113
+ # `:renderable`
114
+ # : Renders the provided object by calling `render_in` with the current view
115
+ # context. The response format is determined by calling `format` on the
116
+ # renderable if it responds to `format`, falling back to `text/html` by
117
+ # default.
118
+ #
119
+ # render renderable: Greeting.new
120
+ # # => renders "<h1>Hello, World</h1>"
91
121
  #
92
- # render json: { hello: "world" }
93
- # # => renders "{\"hello\":\"world\"}"
94
122
  #
95
123
  # By default, when a rendering mode is specified, no layout template is
96
124
  # rendered.
97
125
  #
98
- # ==== Options
126
+ # #### Options
127
+ #
128
+ # `:assigns`
129
+ # : Hash of instance variable assignments for the template.
130
+ #
131
+ # render inline: "<h1>Hello, <%= @name %>!</h1>", assigns: { name: "World" }
132
+ # # => renders "<h1>Hello, World!</h1>"
99
133
  #
100
- # [+:assigns+]
101
- # Hash of instance variable assignments for the template.
134
+ # `:locals`
135
+ # : Hash of local variable assignments for the template.
102
136
  #
103
- # render inline: "<h1>Hello, <%= @name %>!</h1>", assigns: { name: "World" }
104
- # # => renders "<h1>Hello, World!</h1>"
137
+ # render inline: "<h1>Hello, <%= name %>!</h1>", locals: { name: "World" }
138
+ # # => renders "<h1>Hello, World!</h1>"
105
139
  #
106
- # [+:locals+]
107
- # Hash of local variable assignments for the template.
140
+ # `:layout`
141
+ # : The layout template to render. Can also be `false` or `true` to disable or
142
+ # (re)enable the default layout template.
108
143
  #
109
- # render inline: "<h1>Hello, <%= name %>!</h1>", locals: { name: "World" }
110
- # # => renders "<h1>Hello, World!</h1>"
144
+ # render "posts/show", layout: "holiday"
145
+ # # => renders app/views/posts/show.html.erb with the app/views/layouts/holiday.html.erb layout
111
146
  #
112
- # [+:layout+]
113
- # The layout template to render. Can also be +false+ or +true+ to disable
114
- # or (re)enable the default layout template.
147
+ # render "posts/show", layout: false
148
+ # # => renders app/views/posts/show.html.erb with no layout
115
149
  #
116
- # render "posts/show", layout: "holiday"
117
- # # => renders app/views/posts/show.html.erb with the app/views/layouts/holiday.html.erb layout
150
+ # render inline: "<h1>Hello, World!</h1>", layout: true
151
+ # # => renders "<h1>Hello, World!</h1>" with the default layout
118
152
  #
119
- # render "posts/show", layout: false
120
- # # => renders app/views/posts/show.html.erb with no layout
153
+ # `:status`
154
+ # : The HTTP status code to send with the response. Can be specified as a
155
+ # number or as the status name in Symbol form. Defaults to 200.
121
156
  #
122
- # render inline: "<h1>Hello, World!</h1>", layout: true
123
- # # => renders "<h1>Hello, World!</h1>" with the default layout
157
+ # render "posts/new", status: 422
158
+ # # => renders app/views/posts/new.html.erb with HTTP status code 422
124
159
  #
125
- # [+:status+]
126
- # The HTTP status code to send with the response. Can be specified as a
127
- # number or as the status name in Symbol form. Defaults to 200.
160
+ # render "posts/new", status: :unprocessable_entity
161
+ # # => renders app/views/posts/new.html.erb with HTTP status code 422
128
162
  #
129
- # render "posts/new", status: 422
130
- # # => renders app/views/posts/new.html.erb with HTTP status code 422
163
+ # `:variants`
164
+ # : This tells Rails to look for the first template matching any of the variations.
131
165
  #
132
- # render "posts/new", status: :unprocessable_entity
133
- # # => renders app/views/posts/new.html.erb with HTTP status code 422
166
+ # render "posts/index", variants: [:mobile]
167
+ # # => renders app/views/posts/index.html+mobile.erb
134
168
  #
135
169
  #--
136
170
  # Check for double render errors and set the content_type after rendering.
@@ -140,7 +174,7 @@ module ActionController
140
174
  end
141
175
 
142
176
  # Similar to #render, but only returns the rendered template as a string,
143
- # instead of setting +self.response_body+.
177
+ # instead of setting `self.response_body`.
144
178
  #--
145
179
  # Override render_to_string because body can now be set to a Rack body.
146
180
  def render_to_string(*)
@@ -180,7 +214,7 @@ module ActionController
180
214
  end
181
215
 
182
216
  def _set_html_content_type
183
- self.content_type = Mime[:html].to_s
217
+ self.content_type = :html
184
218
  end
185
219
 
186
220
  def _set_rendered_content_type(format)
@@ -204,7 +238,7 @@ module ActionController
204
238
  end
205
239
 
206
240
  if options[:status]
207
- options[:status] = Rack::Utils.status_code(options[:status])
241
+ options[:status] = ActionDispatch::Response.rack_status_code(options[:status])
208
242
  end
209
243
 
210
244
  super