actionpack 7.1.3.2 → 7.2.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +70 -530
- data/lib/abstract_controller/asset_paths.rb +2 -0
- data/lib/abstract_controller/base.rb +102 -98
- data/lib/abstract_controller/caching/fragments.rb +50 -53
- data/lib/abstract_controller/caching.rb +2 -0
- data/lib/abstract_controller/callbacks.rb +66 -64
- data/lib/abstract_controller/collector.rb +6 -6
- data/lib/abstract_controller/deprecator.rb +2 -0
- data/lib/abstract_controller/error.rb +2 -0
- data/lib/abstract_controller/helpers.rb +70 -85
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
- data/lib/abstract_controller/rendering.rb +13 -12
- data/lib/abstract_controller/translation.rb +11 -10
- data/lib/abstract_controller/url_for.rb +8 -6
- data/lib/abstract_controller.rb +2 -0
- data/lib/action_controller/api/api_rendering.rb +2 -0
- data/lib/action_controller/api.rb +74 -72
- data/lib/action_controller/base.rb +155 -117
- data/lib/action_controller/caching.rb +15 -12
- data/lib/action_controller/deprecator.rb +2 -0
- data/lib/action_controller/form_builder.rb +20 -17
- data/lib/action_controller/log_subscriber.rb +3 -1
- data/lib/action_controller/metal/allow_browser.rb +119 -0
- data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
- data/lib/action_controller/metal/conditional_get.rb +188 -174
- data/lib/action_controller/metal/content_security_policy.rb +25 -24
- data/lib/action_controller/metal/cookies.rb +4 -2
- data/lib/action_controller/metal/data_streaming.rb +64 -55
- data/lib/action_controller/metal/default_headers.rb +5 -3
- data/lib/action_controller/metal/etag_with_flash.rb +3 -1
- data/lib/action_controller/metal/etag_with_template_digest.rb +17 -15
- data/lib/action_controller/metal/exceptions.rb +11 -9
- data/lib/action_controller/metal/flash.rb +12 -10
- data/lib/action_controller/metal/head.rb +12 -10
- data/lib/action_controller/metal/helpers.rb +63 -55
- data/lib/action_controller/metal/http_authentication.rb +209 -201
- data/lib/action_controller/metal/implicit_render.rb +17 -15
- data/lib/action_controller/metal/instrumentation.rb +15 -12
- data/lib/action_controller/metal/live.rb +113 -107
- data/lib/action_controller/metal/logging.rb +6 -4
- data/lib/action_controller/metal/mime_responds.rb +151 -142
- data/lib/action_controller/metal/parameter_encoding.rb +34 -32
- data/lib/action_controller/metal/params_wrapper.rb +57 -59
- data/lib/action_controller/metal/permissions_policy.rb +13 -12
- data/lib/action_controller/metal/rate_limiting.rb +62 -0
- data/lib/action_controller/metal/redirecting.rb +108 -82
- data/lib/action_controller/metal/renderers.rb +50 -49
- data/lib/action_controller/metal/rendering.rb +103 -75
- data/lib/action_controller/metal/request_forgery_protection.rb +162 -133
- data/lib/action_controller/metal/rescue.rb +11 -9
- data/lib/action_controller/metal/streaming.rb +138 -136
- data/lib/action_controller/metal/strong_parameters.rb +525 -480
- data/lib/action_controller/metal/testing.rb +2 -0
- data/lib/action_controller/metal/url_for.rb +17 -15
- data/lib/action_controller/metal.rb +58 -57
- data/lib/action_controller/railtie.rb +3 -0
- data/lib/action_controller/railties/helpers.rb +2 -0
- data/lib/action_controller/renderer.rb +42 -36
- data/lib/action_controller/template_assertions.rb +4 -2
- data/lib/action_controller/test_case.rb +146 -126
- data/lib/action_controller.rb +10 -3
- data/lib/action_dispatch/constants.rb +2 -0
- data/lib/action_dispatch/deprecator.rb +2 -0
- data/lib/action_dispatch/http/cache.rb +27 -26
- data/lib/action_dispatch/http/content_disposition.rb +2 -0
- data/lib/action_dispatch/http/content_security_policy.rb +44 -38
- data/lib/action_dispatch/http/filter_parameters.rb +9 -5
- data/lib/action_dispatch/http/filter_redirect.rb +15 -1
- data/lib/action_dispatch/http/headers.rb +22 -22
- data/lib/action_dispatch/http/mime_negotiation.rb +30 -41
- data/lib/action_dispatch/http/mime_type.rb +29 -22
- data/lib/action_dispatch/http/mime_types.rb +2 -0
- data/lib/action_dispatch/http/parameters.rb +11 -9
- data/lib/action_dispatch/http/permissions_policy.rb +20 -37
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +71 -71
- data/lib/action_dispatch/http/response.rb +61 -61
- data/lib/action_dispatch/http/upload.rb +18 -16
- data/lib/action_dispatch/http/url.rb +75 -73
- data/lib/action_dispatch/journey/formatter.rb +13 -6
- data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
- data/lib/action_dispatch/journey/gtg/simulator.rb +2 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +10 -8
- data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
- data/lib/action_dispatch/journey/nodes/node.rb +6 -5
- data/lib/action_dispatch/journey/parser.rb +4 -3
- data/lib/action_dispatch/journey/parser_extras.rb +2 -0
- data/lib/action_dispatch/journey/path/pattern.rb +4 -1
- data/lib/action_dispatch/journey/route.rb +9 -7
- data/lib/action_dispatch/journey/router/utils.rb +16 -15
- data/lib/action_dispatch/journey/router.rb +4 -2
- data/lib/action_dispatch/journey/routes.rb +4 -2
- data/lib/action_dispatch/journey/scanner.rb +4 -2
- data/lib/action_dispatch/journey/visitors.rb +2 -0
- data/lib/action_dispatch/journey.rb +2 -0
- data/lib/action_dispatch/log_subscriber.rb +2 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +2 -0
- data/lib/action_dispatch/middleware/assume_ssl.rb +8 -5
- data/lib/action_dispatch/middleware/callbacks.rb +3 -1
- data/lib/action_dispatch/middleware/cookies.rb +119 -104
- data/lib/action_dispatch/middleware/debug_exceptions.rb +13 -5
- data/lib/action_dispatch/middleware/debug_locks.rb +15 -13
- data/lib/action_dispatch/middleware/debug_view.rb +2 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +6 -11
- data/lib/action_dispatch/middleware/executor.rb +8 -0
- data/lib/action_dispatch/middleware/flash.rb +63 -51
- data/lib/action_dispatch/middleware/host_authorization.rb +17 -15
- data/lib/action_dispatch/middleware/public_exceptions.rb +8 -6
- data/lib/action_dispatch/middleware/reloader.rb +5 -3
- data/lib/action_dispatch/middleware/remote_ip.rb +77 -72
- data/lib/action_dispatch/middleware/request_id.rb +14 -9
- data/lib/action_dispatch/middleware/server_timing.rb +4 -2
- data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +13 -8
- data/lib/action_dispatch/middleware/session/cookie_store.rb +27 -26
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +31 -21
- data/lib/action_dispatch/middleware/ssl.rb +43 -40
- data/lib/action_dispatch/middleware/stack.rb +11 -10
- data/lib/action_dispatch/middleware/static.rb +33 -31
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
- data/lib/action_dispatch/railtie.rb +2 -4
- data/lib/action_dispatch/request/session.rb +23 -21
- data/lib/action_dispatch/request/utils.rb +2 -0
- data/lib/action_dispatch/routing/endpoint.rb +2 -0
- data/lib/action_dispatch/routing/inspector.rb +5 -3
- data/lib/action_dispatch/routing/mapper.rb +670 -635
- data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
- data/lib/action_dispatch/routing/redirection.rb +37 -32
- data/lib/action_dispatch/routing/route_set.rb +59 -45
- data/lib/action_dispatch/routing/routes_proxy.rb +6 -4
- data/lib/action_dispatch/routing/url_for.rb +130 -125
- data/lib/action_dispatch/routing.rb +150 -148
- data/lib/action_dispatch/system_test_case.rb +91 -81
- data/lib/action_dispatch/system_testing/browser.rb +10 -3
- data/lib/action_dispatch/system_testing/driver.rb +3 -1
- data/lib/action_dispatch/system_testing/server.rb +2 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +32 -21
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
- data/lib/action_dispatch/testing/assertion_response.rb +8 -6
- data/lib/action_dispatch/testing/assertions/response.rb +26 -23
- data/lib/action_dispatch/testing/assertions/routing.rb +153 -84
- data/lib/action_dispatch/testing/assertions.rb +2 -0
- data/lib/action_dispatch/testing/integration.rb +223 -222
- data/lib/action_dispatch/testing/request_encoder.rb +2 -0
- data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
- data/lib/action_dispatch/testing/test_process.rb +12 -8
- data/lib/action_dispatch/testing/test_request.rb +3 -1
- data/lib/action_dispatch/testing/test_response.rb +27 -26
- data/lib/action_dispatch.rb +22 -28
- data/lib/action_pack/gem_version.rb +6 -4
- data/lib/action_pack/version.rb +3 -1
- data/lib/action_pack.rb +17 -16
- metadata +30 -13
@@ -1,10 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "action_controller/metal/exceptions"
|
4
6
|
require "action_dispatch/http/content_disposition"
|
5
7
|
|
6
8
|
module ActionController # :nodoc:
|
7
|
-
#
|
9
|
+
# # Action Controller Data Streaming
|
8
10
|
#
|
9
11
|
# Methods for sending arbitrary data and for streaming files to the browser,
|
10
12
|
# instead of rendering.
|
@@ -17,57 +19,60 @@ module ActionController # :nodoc:
|
|
17
19
|
DEFAULT_SEND_FILE_DISPOSITION = "attachment" # :nodoc:
|
18
20
|
|
19
21
|
private
|
20
|
-
# Sends the file. This uses a server-appropriate method (such as
|
21
|
-
# via the
|
22
|
-
#
|
23
|
-
#
|
22
|
+
# Sends the file. This uses a server-appropriate method (such as `X-Sendfile`)
|
23
|
+
# via the `Rack::Sendfile` middleware. The header to use is set via
|
24
|
+
# `config.action_dispatch.x_sendfile_header`. Your server can also configure
|
25
|
+
# this for you by setting the `X-Sendfile-Type` header.
|
24
26
|
#
|
25
|
-
# Be careful to sanitize the path parameter if it is coming from a web
|
26
|
-
#
|
27
|
-
#
|
27
|
+
# Be careful to sanitize the path parameter if it is coming from a web page.
|
28
|
+
# `send_file(params[:path])` allows a malicious user to download any file on
|
29
|
+
# your server.
|
28
30
|
#
|
29
31
|
# Options:
|
30
|
-
# *
|
31
|
-
#
|
32
|
-
# *
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
# *
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
32
|
+
# * `:filename` - suggests a filename for the browser to use. Defaults to
|
33
|
+
# `File.basename(path)`.
|
34
|
+
# * `:type` - specifies an HTTP content type. You can specify either a string
|
35
|
+
# or a symbol for a registered type with `Mime::Type.register`, for example
|
36
|
+
# `:json`. If omitted, the type will be inferred from the file extension
|
37
|
+
# specified in `:filename`. If no content type is registered for the
|
38
|
+
# extension, the default type `application/octet-stream` will be used.
|
39
|
+
# * `:disposition` - specifies whether the file will be shown inline or
|
40
|
+
# downloaded. Valid values are `"inline"` and `"attachment"` (default).
|
41
|
+
# * `:status` - specifies the status code to send with the response. Defaults
|
42
|
+
# to 200.
|
43
|
+
# * `:url_based_filename` - set to `true` if you want the browser to guess the
|
44
|
+
# filename from the URL, which is necessary for i18n filenames on certain
|
45
|
+
# browsers (setting `:filename` overrides this option).
|
46
|
+
#
|
47
|
+
#
|
48
|
+
# The default `Content-Type` and `Content-Disposition` headers are set to
|
49
|
+
# download arbitrary binary files in as many browsers as possible. IE versions
|
50
|
+
# 4, 5, 5.5, and 6 are all known to have a variety of quirks (especially when
|
51
|
+
# downloading over SSL).
|
47
52
|
#
|
48
53
|
# Simple download:
|
49
54
|
#
|
50
|
-
#
|
55
|
+
# send_file '/path/to.zip'
|
51
56
|
#
|
52
57
|
# Show a JPEG in the browser:
|
53
58
|
#
|
54
|
-
#
|
59
|
+
# send_file '/path/to.jpeg', type: 'image/jpeg', disposition: 'inline'
|
55
60
|
#
|
56
61
|
# Show a 404 page in the browser:
|
57
62
|
#
|
58
|
-
#
|
63
|
+
# send_file '/path/to/404.html', type: 'text/html; charset=utf-8', disposition: 'inline', status: 404
|
59
64
|
#
|
60
|
-
# You can use other
|
61
|
-
#
|
62
|
-
#
|
65
|
+
# You can use other `Content-*` HTTP headers to provide additional information
|
66
|
+
# to the client. See MDN for a [list of HTTP
|
67
|
+
# headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers).
|
63
68
|
#
|
64
|
-
# Also be aware that the document may be cached by proxies and browsers.
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
69
|
+
# Also be aware that the document may be cached by proxies and browsers. The
|
70
|
+
# `Pragma` and `Cache-Control` headers declare how the file may be cached by
|
71
|
+
# intermediaries. They default to require clients to validate with the server
|
72
|
+
# before releasing cached responses. See https://www.mnot.net/cache_docs/ for an
|
73
|
+
# overview of web caching and [RFC
|
74
|
+
# 9111](https://www.rfc-editor.org/rfc/rfc9111.html#name-cache-control) for the
|
75
|
+
# `Cache-Control` header spec.
|
71
76
|
def send_file(path, options = {}) # :doc:
|
72
77
|
raise MissingFile, "Cannot read file #{path}" unless File.file?(path) && File.readable?(path)
|
73
78
|
|
@@ -79,35 +84,39 @@ module ActionController # :nodoc:
|
|
79
84
|
response.send_file path
|
80
85
|
end
|
81
86
|
|
82
|
-
# Sends the given binary data to the browser. This method is similar to
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
+
# Sends the given binary data to the browser. This method is similar to `render
|
88
|
+
# plain: data`, but also allows you to specify whether the browser should
|
89
|
+
# display the response as a file attachment (i.e. in a download dialog) or as
|
90
|
+
# inline data. You may also set the content type, the file name, and other
|
91
|
+
# things.
|
87
92
|
#
|
88
93
|
# Options:
|
89
|
-
# *
|
90
|
-
# *
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
#
|
95
|
-
#
|
96
|
-
# *
|
94
|
+
# * `:filename` - suggests a filename for the browser to use.
|
95
|
+
# * `:type` - specifies an HTTP content type. Defaults to
|
96
|
+
# `application/octet-stream`. You can specify either a string or a symbol
|
97
|
+
# for a registered type with `Mime::Type.register`, for example `:json`. If
|
98
|
+
# omitted, type will be inferred from the file extension specified in
|
99
|
+
# `:filename`. If no content type is registered for the extension, the
|
100
|
+
# default type `application/octet-stream` will be used.
|
101
|
+
# * `:disposition` - specifies whether the file will be shown inline or
|
102
|
+
# downloaded. Valid values are `"inline"` and `"attachment"` (default).
|
103
|
+
# * `:status` - specifies the status code to send with the response. Defaults
|
104
|
+
# to 200.
|
105
|
+
#
|
97
106
|
#
|
98
107
|
# Generic data download:
|
99
108
|
#
|
100
|
-
#
|
109
|
+
# send_data buffer
|
101
110
|
#
|
102
111
|
# Download a dynamically-generated tarball:
|
103
112
|
#
|
104
|
-
#
|
113
|
+
# send_data generate_tgz('dir'), filename: 'dir.tgz'
|
105
114
|
#
|
106
115
|
# Display an image Active Record in the browser:
|
107
116
|
#
|
108
|
-
#
|
117
|
+
# send_data image.data, type: image.content_type, disposition: 'inline'
|
109
118
|
#
|
110
|
-
# See
|
119
|
+
# See `send_file` for more information on HTTP `Content-*` headers and caching.
|
111
120
|
def send_data(data, options = {}) # :doc:
|
112
121
|
send_file_headers! options
|
113
122
|
render options.slice(:status, :content_type).merge(body: data)
|
@@ -1,10 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionController
|
4
|
-
#
|
6
|
+
# # Action Controller Default Headers
|
5
7
|
#
|
6
|
-
# Allows configuring default headers that will be automatically merged into
|
7
|
-
#
|
8
|
+
# Allows configuring default headers that will be automatically merged into each
|
9
|
+
# response.
|
8
10
|
module DefaultHeaders
|
9
11
|
extend ActiveSupport::Concern
|
10
12
|
|
@@ -1,7 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionController
|
4
|
-
#
|
6
|
+
# # Action Controller Etag With Flash
|
5
7
|
#
|
6
8
|
# When you're using the flash, it's generally used as a conditional on the view.
|
7
9
|
# This means the content of the view depends on the flash. Which in turn means
|
@@ -1,24 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionController
|
4
|
-
#
|
6
|
+
# # Action Controller Etag With Template Digest
|
5
7
|
#
|
6
|
-
# When our views change, they should bubble up into HTTP cache freshness
|
7
|
-
#
|
8
|
-
#
|
8
|
+
# When our views change, they should bubble up into HTTP cache freshness and
|
9
|
+
# bust browser caches. So the template digest for the current action is
|
10
|
+
# automatically included in the ETag.
|
9
11
|
#
|
10
12
|
# Enabled by default for apps that use Action View. Disable by setting
|
11
13
|
#
|
12
|
-
#
|
14
|
+
# config.action_controller.etag_with_template_digest = false
|
13
15
|
#
|
14
|
-
# Override the template to digest by passing
|
15
|
-
#
|
16
|
+
# Override the template to digest by passing `:template` to `fresh_when` and
|
17
|
+
# `stale?` calls. For example:
|
16
18
|
#
|
17
|
-
#
|
18
|
-
#
|
19
|
+
# # We're going to render widgets/show, not posts/show
|
20
|
+
# fresh_when @post, template: 'widgets/show'
|
19
21
|
#
|
20
|
-
#
|
21
|
-
#
|
22
|
+
# # We're not going to render a template, so omit it from the ETag.
|
23
|
+
# fresh_when @post, template: false
|
22
24
|
#
|
23
25
|
module EtagWithTemplateDigest
|
24
26
|
extend ActiveSupport::Concern
|
@@ -40,10 +42,10 @@ module ActionController
|
|
40
42
|
end
|
41
43
|
end
|
42
44
|
|
43
|
-
# Pick the template digest to include in the ETag. If the
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
45
|
+
# Pick the template digest to include in the ETag. If the `:template` option is
|
46
|
+
# present, use the named template. If `:template` is `nil` or absent, use the
|
47
|
+
# default controller/action template. If `:template` is false, omit the template
|
48
|
+
# digest from the ETag.
|
47
49
|
def pick_template_for_etag(options)
|
48
50
|
unless options[:template] == false
|
49
51
|
options[:template] || lookup_context.find_all(action_name, _prefixes).first&.virtual_path
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionController
|
4
6
|
class ActionControllerError < StandardError # :nodoc:
|
5
7
|
end
|
@@ -73,16 +75,16 @@ module ActionController
|
|
73
75
|
class UnknownFormat < ActionControllerError # :nodoc:
|
74
76
|
end
|
75
77
|
|
76
|
-
# Raised when a nested respond_to is triggered and the content types of each
|
77
|
-
#
|
78
|
+
# Raised when a nested respond_to is triggered and the content types of each are
|
79
|
+
# incompatible. For example:
|
78
80
|
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
81
|
+
# respond_to do |outer_type|
|
82
|
+
# outer_type.js do
|
83
|
+
# respond_to do |inner_type|
|
84
|
+
# inner_type.html { render body: "HTML" }
|
85
|
+
# end
|
86
|
+
# end
|
87
|
+
# end
|
86
88
|
class RespondToMismatchError < ActionControllerError
|
87
89
|
DEFAULT_MESSAGE = "respond_to was called multiple times and matched with conflicting formats in this action. Please note that you may only call respond_to and match on a single format per action."
|
88
90
|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionController # :nodoc:
|
4
6
|
module Flash
|
5
7
|
extend ActiveSupport::Concern
|
@@ -13,19 +15,19 @@ module ActionController # :nodoc:
|
|
13
15
|
|
14
16
|
module ClassMethods
|
15
17
|
# Creates new flash types. You can pass as many types as you want to create
|
16
|
-
# flash types other than the default
|
17
|
-
#
|
18
|
+
# flash types other than the default `alert` and `notice` in your controllers
|
19
|
+
# and views. For instance:
|
18
20
|
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
21
|
+
# # in application_controller.rb
|
22
|
+
# class ApplicationController < ActionController::Base
|
23
|
+
# add_flash_types :warning
|
24
|
+
# end
|
23
25
|
#
|
24
|
-
#
|
25
|
-
#
|
26
|
+
# # in your controller
|
27
|
+
# redirect_to user_path(@user), warning: "Incomplete profile"
|
26
28
|
#
|
27
|
-
#
|
28
|
-
#
|
29
|
+
# # in your view
|
30
|
+
# <%= warning %>
|
29
31
|
#
|
30
32
|
# This method will automatically define a new method for each of the given
|
31
33
|
# names, and it will be available in your views.
|
@@ -1,23 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionController
|
4
6
|
module Head
|
5
|
-
# Returns a response that has no content (merely headers). The options
|
6
|
-
#
|
7
|
-
#
|
8
|
-
# significant headers:
|
7
|
+
# Returns a response that has no content (merely headers). The options argument
|
8
|
+
# is interpreted to be a hash of header names and values. This allows you to
|
9
|
+
# easily return a response that consists only of significant headers:
|
9
10
|
#
|
10
|
-
#
|
11
|
+
# head :created, location: person_path(@person)
|
11
12
|
#
|
12
|
-
#
|
13
|
+
# head :created, location: @person
|
13
14
|
#
|
14
15
|
# It can also be used to return exceptional conditions:
|
15
16
|
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
17
|
+
# return head(:method_not_allowed) unless request.post?
|
18
|
+
# return head(:bad_request) unless valid_request?
|
19
|
+
# render
|
19
20
|
#
|
20
|
-
# See
|
21
|
+
# See `Rack::Utils::SYMBOL_TO_STATUS_CODE` for a full list of valid `status`
|
22
|
+
# symbols.
|
21
23
|
def head(status, options = nil)
|
22
24
|
if status.is_a?(Hash)
|
23
25
|
raise ArgumentError, "#{status.inspect} is not a valid value for `status`."
|
@@ -1,59 +1,64 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionController
|
4
|
-
#
|
6
|
+
# # Action Controller Helpers
|
5
7
|
#
|
6
|
-
# The
|
7
|
-
# numbers and model objects, to name a few. These helpers
|
8
|
-
# by default.
|
8
|
+
# The Rails framework provides a large number of helpers for working with
|
9
|
+
# assets, dates, forms, numbers and model objects, to name a few. These helpers
|
10
|
+
# are available to all templates by default.
|
9
11
|
#
|
10
|
-
# In addition to using the standard template helpers provided, creating custom
|
11
|
-
# extract complicated logic or reusable functionality is strongly
|
12
|
-
# will include all helpers. These
|
12
|
+
# In addition to using the standard template helpers provided, creating custom
|
13
|
+
# helpers to extract complicated logic or reusable functionality is strongly
|
14
|
+
# encouraged. By default, each controller will include all helpers. These
|
15
|
+
# helpers are only accessible on the controller through `#helpers`
|
13
16
|
#
|
14
|
-
# In previous versions of
|
15
|
-
# matches the name of the controller, e.g.,
|
16
|
-
# include
|
17
|
+
# In previous versions of Rails the controller will include a helper which
|
18
|
+
# matches the name of the controller, e.g., `MyController` will automatically
|
19
|
+
# include `MyHelper`. You can revert to the old behavior with the following:
|
17
20
|
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
21
|
+
# # config/application.rb
|
22
|
+
# class Application < Rails::Application
|
23
|
+
# config.action_controller.include_all_helpers = false
|
24
|
+
# end
|
22
25
|
#
|
23
|
-
# Additional helpers can be specified using the
|
24
|
-
# controller which inherits from it.
|
26
|
+
# Additional helpers can be specified using the `helper` class method in
|
27
|
+
# ActionController::Base or any controller which inherits from it.
|
25
28
|
#
|
26
|
-
# The
|
27
|
-
# a
|
29
|
+
# The `to_s` method from the Time class can be wrapped in a helper method to
|
30
|
+
# display a custom message if a Time object is blank:
|
28
31
|
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
+
# module FormattedTimeHelper
|
33
|
+
# def format_time(time, format=:long, blank_message=" ")
|
34
|
+
# time.blank? ? blank_message : time.to_fs(format)
|
35
|
+
# end
|
32
36
|
# end
|
33
|
-
# end
|
34
37
|
#
|
35
|
-
# FormattedTimeHelper can now be included in a controller, using the
|
38
|
+
# FormattedTimeHelper can now be included in a controller, using the `helper`
|
39
|
+
# class method:
|
36
40
|
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
+
# class EventsController < ActionController::Base
|
42
|
+
# helper FormattedTimeHelper
|
43
|
+
# def index
|
44
|
+
# @events = Event.all
|
45
|
+
# end
|
41
46
|
# end
|
42
|
-
# end
|
43
47
|
#
|
44
|
-
# Then, in any view rendered by
|
48
|
+
# Then, in any view rendered by `EventsController`, the `format_time` method can
|
49
|
+
# be called:
|
45
50
|
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
51
|
+
# <% @events.each do |event| -%>
|
52
|
+
# <p>
|
53
|
+
# <%= format_time(event.time, :short, "N/A") %> | <%= event.name %>
|
54
|
+
# </p>
|
55
|
+
# <% end -%>
|
51
56
|
#
|
52
|
-
# Finally, assuming we have two event instances, one which has a time and one
|
53
|
-
# the output might look like this:
|
57
|
+
# Finally, assuming we have two event instances, one which has a time and one
|
58
|
+
# which does not, the output might look like this:
|
54
59
|
#
|
55
|
-
#
|
56
|
-
#
|
60
|
+
# 23 Aug 11:30 | Carolina Railhawks Soccer Match
|
61
|
+
# N/A | Carolina Railhawks Training Workshop
|
57
62
|
#
|
58
63
|
module Helpers
|
59
64
|
extend ActiveSupport::Concern
|
@@ -68,23 +73,24 @@ module ActionController
|
|
68
73
|
|
69
74
|
module ClassMethods
|
70
75
|
# Declares helper accessors for controller attributes. For example, the
|
71
|
-
# following adds new
|
72
|
-
#
|
73
|
-
#
|
74
|
-
#
|
76
|
+
# following adds new `name` and `name=` instance methods to a controller and
|
77
|
+
# makes them available to the view:
|
78
|
+
# attr_accessor :name
|
79
|
+
# helper_attr :name
|
80
|
+
#
|
81
|
+
# #### Parameters
|
82
|
+
# * `attrs` - Names of attributes to be converted into helpers.
|
75
83
|
#
|
76
|
-
# ==== Parameters
|
77
|
-
# * <tt>attrs</tt> - Names of attributes to be converted into helpers.
|
78
84
|
def helper_attr(*attrs)
|
79
85
|
attrs.flatten.each { |attr| helper_method(attr, "#{attr}=") }
|
80
86
|
end
|
81
87
|
|
82
88
|
# Provides a proxy to access helper methods from outside the view.
|
83
89
|
#
|
84
|
-
# Note that the proxy is rendered under a different view context.
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
90
|
+
# Note that the proxy is rendered under a different view context. This may cause
|
91
|
+
# incorrect behavior with capture methods. Consider using
|
92
|
+
# [helper](rdoc-ref:AbstractController::Helpers::ClassMethods#helper) instead
|
93
|
+
# when using `capture`.
|
88
94
|
def helpers
|
89
95
|
@helper_proxy ||= begin
|
90
96
|
proxy = ActionView::Base.empty
|
@@ -93,21 +99,23 @@ module ActionController
|
|
93
99
|
end
|
94
100
|
end
|
95
101
|
|
96
|
-
# Override modules_for_helpers to accept
|
97
|
-
#
|
102
|
+
# Override modules_for_helpers to accept `:all` as argument, which loads all
|
103
|
+
# helpers in helpers_path.
|
104
|
+
#
|
105
|
+
# #### Parameters
|
106
|
+
# * `args` - A list of helpers
|
107
|
+
#
|
98
108
|
#
|
99
|
-
#
|
100
|
-
# *
|
109
|
+
# #### Returns
|
110
|
+
# * `array` - A normalized list of modules for the list of helpers provided.
|
101
111
|
#
|
102
|
-
# ==== Returns
|
103
|
-
# * <tt>array</tt> - A normalized list of modules for the list of helpers provided.
|
104
112
|
def modules_for_helpers(args)
|
105
113
|
args += all_application_helpers if args.delete(:all)
|
106
114
|
super(args)
|
107
115
|
end
|
108
116
|
|
109
117
|
private
|
110
|
-
# Extract helper names from files in
|
118
|
+
# Extract helper names from files in `app/helpers/***/**_helper.rb`
|
111
119
|
def all_application_helpers
|
112
120
|
all_helpers_from_path(helpers_path)
|
113
121
|
end
|