actionpack 4.2.10 → 6.1.3.2
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 +5 -5
- data/CHANGELOG.md +291 -479
- data/MIT-LICENSE +1 -1
- data/README.rdoc +9 -9
- data/lib/abstract_controller/asset_paths.rb +2 -0
- data/lib/abstract_controller/base.rb +81 -51
- data/lib/{action_controller → abstract_controller}/caching/fragments.rb +64 -17
- data/lib/abstract_controller/caching.rb +66 -0
- data/lib/abstract_controller/callbacks.rb +61 -33
- data/lib/abstract_controller/collector.rb +9 -13
- data/lib/abstract_controller/error.rb +6 -0
- data/lib/abstract_controller/helpers.rb +115 -99
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +21 -3
- data/lib/abstract_controller/rendering.rb +48 -47
- data/lib/abstract_controller/translation.rb +17 -8
- data/lib/abstract_controller/url_for.rb +2 -0
- data/lib/abstract_controller.rb +13 -5
- data/lib/action_controller/api/api_rendering.rb +16 -0
- data/lib/action_controller/api.rb +150 -0
- data/lib/action_controller/base.rb +29 -24
- data/lib/action_controller/caching.rb +12 -57
- data/lib/action_controller/form_builder.rb +50 -0
- data/lib/action_controller/log_subscriber.rb +17 -19
- data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
- data/lib/action_controller/metal/conditional_get.rb +134 -46
- data/lib/action_controller/metal/content_security_policy.rb +51 -0
- data/lib/action_controller/metal/cookies.rb +6 -4
- data/lib/action_controller/metal/data_streaming.rb +30 -50
- data/lib/action_controller/metal/default_headers.rb +17 -0
- data/lib/action_controller/metal/etag_with_flash.rb +18 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +21 -16
- data/lib/action_controller/metal/exceptions.rb +63 -15
- data/lib/action_controller/metal/flash.rb +9 -8
- data/lib/action_controller/metal/head.rb +26 -21
- data/lib/action_controller/metal/helpers.rb +37 -18
- data/lib/action_controller/metal/http_authentication.rb +81 -73
- data/lib/action_controller/metal/implicit_render.rb +53 -9
- data/lib/action_controller/metal/instrumentation.rb +32 -35
- data/lib/action_controller/metal/live.rb +102 -120
- data/lib/action_controller/metal/logging.rb +20 -0
- data/lib/action_controller/metal/mime_responds.rb +49 -47
- data/lib/action_controller/metal/parameter_encoding.rb +82 -0
- data/lib/action_controller/metal/params_wrapper.rb +83 -66
- data/lib/action_controller/metal/permissions_policy.rb +46 -0
- data/lib/action_controller/metal/redirecting.rb +53 -32
- data/lib/action_controller/metal/renderers.rb +87 -44
- data/lib/action_controller/metal/rendering.rb +77 -50
- data/lib/action_controller/metal/request_forgery_protection.rb +267 -103
- data/lib/action_controller/metal/rescue.rb +10 -17
- data/lib/action_controller/metal/streaming.rb +12 -11
- data/lib/action_controller/metal/strong_parameters.rb +714 -186
- data/lib/action_controller/metal/testing.rb +2 -17
- data/lib/action_controller/metal/url_for.rb +19 -10
- data/lib/action_controller/metal.rb +104 -87
- data/lib/action_controller/railtie.rb +28 -10
- data/lib/action_controller/railties/helpers.rb +3 -1
- data/lib/action_controller/renderer.rb +141 -0
- data/lib/action_controller/template_assertions.rb +11 -0
- data/lib/action_controller/test_case.rb +296 -422
- data/lib/action_controller.rb +34 -23
- data/lib/action_dispatch/http/cache.rb +107 -56
- data/lib/action_dispatch/http/content_disposition.rb +45 -0
- data/lib/action_dispatch/http/content_security_policy.rb +286 -0
- data/lib/action_dispatch/http/filter_parameters.rb +32 -25
- data/lib/action_dispatch/http/filter_redirect.rb +10 -12
- data/lib/action_dispatch/http/headers.rb +55 -22
- data/lib/action_dispatch/http/mime_negotiation.rb +82 -50
- data/lib/action_dispatch/http/mime_type.rb +153 -121
- data/lib/action_dispatch/http/mime_types.rb +20 -6
- data/lib/action_dispatch/http/parameters.rb +90 -40
- data/lib/action_dispatch/http/permissions_policy.rb +173 -0
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +226 -121
- data/lib/action_dispatch/http/response.rb +248 -113
- data/lib/action_dispatch/http/upload.rb +21 -7
- data/lib/action_dispatch/http/url.rb +182 -100
- data/lib/action_dispatch/journey/formatter.rb +90 -43
- data/lib/action_dispatch/journey/gtg/builder.rb +28 -41
- data/lib/action_dispatch/journey/gtg/simulator.rb +11 -16
- data/lib/action_dispatch/journey/gtg/transition_table.rb +23 -21
- data/lib/action_dispatch/journey/nfa/dot.rb +3 -14
- data/lib/action_dispatch/journey/nodes/node.rb +29 -15
- data/lib/action_dispatch/journey/parser.rb +17 -16
- data/lib/action_dispatch/journey/parser.y +4 -3
- data/lib/action_dispatch/journey/parser_extras.rb +12 -4
- data/lib/action_dispatch/journey/path/pattern.rb +58 -54
- data/lib/action_dispatch/journey/route.rb +100 -32
- data/lib/action_dispatch/journey/router/utils.rb +29 -18
- data/lib/action_dispatch/journey/router.rb +55 -51
- data/lib/action_dispatch/journey/routes.rb +17 -17
- data/lib/action_dispatch/journey/scanner.rb +26 -17
- data/lib/action_dispatch/journey/visitors.rb +98 -54
- data/lib/action_dispatch/journey.rb +5 -5
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
- data/lib/action_dispatch/middleware/callbacks.rb +3 -6
- data/lib/action_dispatch/middleware/cookies.rb +347 -217
- data/lib/action_dispatch/middleware/debug_exceptions.rb +135 -63
- data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
- data/lib/action_dispatch/middleware/debug_view.rb +66 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +115 -71
- data/lib/action_dispatch/middleware/executor.rb +21 -0
- data/lib/action_dispatch/middleware/flash.rb +78 -54
- data/lib/action_dispatch/middleware/host_authorization.rb +130 -0
- data/lib/action_dispatch/middleware/public_exceptions.rb +32 -27
- data/lib/action_dispatch/middleware/reloader.rb +5 -91
- data/lib/action_dispatch/middleware/remote_ip.rb +53 -45
- data/lib/action_dispatch/middleware/request_id.rb +17 -10
- data/lib/action_dispatch/middleware/session/abstract_store.rb +41 -26
- data/lib/action_dispatch/middleware/session/cache_store.rb +24 -14
- data/lib/action_dispatch/middleware/session/cookie_store.rb +74 -75
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -2
- data/lib/action_dispatch/middleware/show_exceptions.rb +28 -23
- data/lib/action_dispatch/middleware/ssl.rb +118 -35
- data/lib/action_dispatch/middleware/stack.rb +82 -41
- data/lib/action_dispatch/middleware/static.rb +156 -89
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
- data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -14
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +4 -2
- data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +45 -35
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +23 -4
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +15 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +105 -8
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +87 -64
- data/lib/action_dispatch/railtie.rb +27 -13
- data/lib/action_dispatch/request/session.rb +109 -61
- data/lib/action_dispatch/request/utils.rb +90 -23
- data/lib/action_dispatch/routing/endpoint.rb +9 -2
- data/lib/action_dispatch/routing/inspector.rb +141 -102
- data/lib/action_dispatch/routing/mapper.rb +811 -473
- data/lib/action_dispatch/routing/polymorphic_routes.rb +167 -143
- data/lib/action_dispatch/routing/redirection.rb +37 -27
- data/lib/action_dispatch/routing/route_set.rb +363 -331
- data/lib/action_dispatch/routing/routes_proxy.rb +32 -5
- data/lib/action_dispatch/routing/url_for.rb +66 -26
- data/lib/action_dispatch/routing.rb +36 -36
- data/lib/action_dispatch/system_test_case.rb +190 -0
- data/lib/action_dispatch/system_testing/browser.rb +86 -0
- data/lib/action_dispatch/system_testing/driver.rb +67 -0
- data/lib/action_dispatch/system_testing/server.rb +31 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +138 -0
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +29 -0
- data/lib/action_dispatch/testing/assertion_response.rb +46 -0
- data/lib/action_dispatch/testing/assertions/response.rb +44 -22
- data/lib/action_dispatch/testing/assertions/routing.rb +47 -31
- data/lib/action_dispatch/testing/assertions.rb +6 -4
- data/lib/action_dispatch/testing/integration.rb +391 -220
- data/lib/action_dispatch/testing/request_encoder.rb +55 -0
- data/lib/action_dispatch/testing/test_process.rb +53 -22
- data/lib/action_dispatch/testing/test_request.rb +27 -34
- data/lib/action_dispatch/testing/test_response.rb +11 -11
- data/lib/action_dispatch.rb +35 -21
- data/lib/action_pack/gem_version.rb +6 -4
- data/lib/action_pack/version.rb +3 -1
- data/lib/action_pack.rb +4 -2
- metadata +78 -49
- data/lib/action_controller/metal/force_ssl.rb +0 -97
- data/lib/action_controller/metal/hide_actions.rb +0 -40
- data/lib/action_controller/metal/rack_delegation.rb +0 -32
- data/lib/action_controller/middleware.rb +0 -39
- data/lib/action_controller/model_naming.rb +0 -12
- data/lib/action_dispatch/http/parameter_filter.rb +0 -72
- data/lib/action_dispatch/journey/backwards.rb +0 -5
- data/lib/action_dispatch/journey/nfa/builder.rb +0 -76
- data/lib/action_dispatch/journey/nfa/simulator.rb +0 -47
- data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -163
- data/lib/action_dispatch/journey/router/strexp.rb +0 -27
- data/lib/action_dispatch/middleware/params_parser.rb +0 -60
- data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
- data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
- data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
@@ -1,14 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "action_dispatch/http/mime_type"
|
2
4
|
|
3
5
|
module AbstractController
|
4
6
|
module Collector
|
5
7
|
def self.generate_method_for_mime(mime)
|
6
8
|
sym = mime.is_a?(Symbol) ? mime : mime.to_sym
|
7
|
-
const = sym.upcase
|
8
9
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
9
|
-
def #{sym}(*args, &block)
|
10
|
-
custom(Mime
|
11
|
-
end
|
10
|
+
def #{sym}(*args, &block)
|
11
|
+
custom(Mime[:#{sym}], *args, &block)
|
12
|
+
end
|
12
13
|
RUBY
|
13
14
|
end
|
14
15
|
|
@@ -17,24 +18,19 @@ module AbstractController
|
|
17
18
|
end
|
18
19
|
|
19
20
|
Mime::Type.register_callback do |mime|
|
20
|
-
generate_method_for_mime(mime) unless
|
21
|
+
generate_method_for_mime(mime) unless instance_methods.include?(mime.to_sym)
|
21
22
|
end
|
22
23
|
|
23
|
-
|
24
|
-
|
24
|
+
private
|
25
25
|
def method_missing(symbol, &block)
|
26
|
-
|
27
|
-
|
28
|
-
unless Mime.const_defined?(const_name)
|
26
|
+
unless mime_constant = Mime[symbol]
|
29
27
|
raise NoMethodError, "To respond to a custom format, register it as a MIME type first: " \
|
30
|
-
"
|
28
|
+
"https://guides.rubyonrails.org/action_controller_overview.html#restful-downloads. " \
|
31
29
|
"If you meant to respond to a variant like :tablet or :phone, not a custom format, " \
|
32
30
|
"be sure to nest your variant response within a format response: " \
|
33
31
|
"format.html { |html| html.tablet { ... } }"
|
34
32
|
end
|
35
33
|
|
36
|
-
mime_constant = Mime.const_get(const_name)
|
37
|
-
|
38
34
|
if Mime::SET.include?(mime_constant)
|
39
35
|
AbstractController::Collector.generate_method_for_mime(mime_constant)
|
40
36
|
send(symbol, &block)
|
@@ -1,15 +1,25 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/dependencies"
|
2
4
|
|
3
5
|
module AbstractController
|
4
6
|
module Helpers
|
5
7
|
extend ActiveSupport::Concern
|
6
8
|
|
7
9
|
included do
|
8
|
-
class_attribute :
|
9
|
-
|
10
|
+
class_attribute :_helper_methods, default: Array.new
|
11
|
+
|
12
|
+
# This is here so that it is always higher in the inheritance chain than
|
13
|
+
# the definition in lib/action_view/rendering.rb
|
14
|
+
redefine_singleton_method(:_helpers) do
|
15
|
+
if @_helpers ||= nil
|
16
|
+
@_helpers
|
17
|
+
else
|
18
|
+
superclass._helpers
|
19
|
+
end
|
20
|
+
end
|
10
21
|
|
11
|
-
|
12
|
-
self._helper_methods = Array.new
|
22
|
+
self._helpers = define_helpers_module(self)
|
13
23
|
end
|
14
24
|
|
15
25
|
class MissingHelperError < LoadError
|
@@ -18,7 +28,7 @@ module AbstractController
|
|
18
28
|
@path = "helpers/#{path}.rb"
|
19
29
|
set_backtrace error.backtrace
|
20
30
|
|
21
|
-
if
|
31
|
+
if /^#{path}(\.rb)?$/.match?(error.path)
|
22
32
|
super("Missing helper file helpers/%s.rb" % path)
|
23
33
|
else
|
24
34
|
raise error
|
@@ -26,19 +36,27 @@ module AbstractController
|
|
26
36
|
end
|
27
37
|
end
|
28
38
|
|
39
|
+
def _helpers
|
40
|
+
self.class._helpers
|
41
|
+
end
|
42
|
+
|
29
43
|
module ClassMethods
|
30
44
|
# When a class is inherited, wrap its helper module in a new module.
|
31
45
|
# This ensures that the parent class's module can be changed
|
32
46
|
# independently of the child class's.
|
33
47
|
def inherited(klass)
|
34
|
-
|
35
|
-
klass._helpers =
|
48
|
+
# Inherited from parent by default
|
49
|
+
klass._helpers = nil
|
50
|
+
|
36
51
|
klass.class_eval { default_helper_module! } unless klass.anonymous?
|
37
52
|
super
|
38
53
|
end
|
39
54
|
|
55
|
+
attr_writer :_helpers
|
56
|
+
|
40
57
|
# Declare a controller method as a helper. For example, the following
|
41
|
-
# makes the +current_user+ controller
|
58
|
+
# makes the +current_user+ and +logged_in?+ controller methods available
|
59
|
+
# to the view:
|
42
60
|
# class ApplicationController < ActionController::Base
|
43
61
|
# helper_method :current_user, :logged_in?
|
44
62
|
#
|
@@ -57,59 +75,81 @@ module AbstractController
|
|
57
75
|
# ==== Parameters
|
58
76
|
# * <tt>method[, method]</tt> - A name or names of a method on the controller
|
59
77
|
# to be made available on the view.
|
60
|
-
def helper_method(*
|
61
|
-
|
62
|
-
self._helper_methods +=
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
78
|
+
def helper_method(*methods)
|
79
|
+
methods.flatten!
|
80
|
+
self._helper_methods += methods
|
81
|
+
|
82
|
+
location = caller_locations(1, 1).first
|
83
|
+
file, line = location.path, location.lineno
|
84
|
+
|
85
|
+
methods.each do |method|
|
86
|
+
_helpers_for_modification.class_eval <<-ruby_eval, file, line
|
87
|
+
def #{method}(*args, &block) # def current_user(*args, &block)
|
88
|
+
controller.send(:'#{method}', *args, &block) # controller.send(:'current_user', *args, &block)
|
89
|
+
end # end
|
90
|
+
ruby2_keywords(:'#{method}') if respond_to?(:ruby2_keywords, true)
|
69
91
|
ruby_eval
|
70
92
|
end
|
71
93
|
end
|
72
94
|
|
73
|
-
#
|
95
|
+
# Includes the given modules in the template class.
|
96
|
+
#
|
97
|
+
# Modules can be specified in different ways. All of the following calls
|
98
|
+
# include +FooHelper+:
|
99
|
+
#
|
100
|
+
# # Module, recommended.
|
101
|
+
# helper FooHelper
|
102
|
+
#
|
103
|
+
# # String/symbol without the "helper" suffix, camel or snake case.
|
104
|
+
# helper "Foo"
|
105
|
+
# helper :Foo
|
106
|
+
# helper "foo"
|
107
|
+
# helper :foo
|
74
108
|
#
|
75
|
-
#
|
76
|
-
# * <tt>*args</tt> - Module, Symbol, String
|
77
|
-
# * <tt>block</tt> - A block defining helper methods
|
109
|
+
# The last two assume that <tt>"foo".camelize</tt> returns "Foo".
|
78
110
|
#
|
79
|
-
# When
|
80
|
-
#
|
111
|
+
# When strings or symbols are passed, the method finds the actual module
|
112
|
+
# object using +String#constantize+. Therefore, if the module has not been
|
113
|
+
# yet loaded, it has to be autoloadable, which is normally the case.
|
81
114
|
#
|
82
|
-
#
|
83
|
-
# and include the module in the template class. The second form illustrates how to include custom helpers
|
84
|
-
# when working with namespaced controllers, or other cases where the file containing the helper definition is not
|
85
|
-
# in one of Rails' standard load paths:
|
86
|
-
# helper :foo # => requires 'foo_helper' and includes FooHelper
|
87
|
-
# helper 'resources/foo' # => requires 'resources/foo_helper' and includes Resources::FooHelper
|
115
|
+
# Namespaces are supported. The following calls include +Foo::BarHelper+:
|
88
116
|
#
|
89
|
-
#
|
90
|
-
#
|
117
|
+
# # Module, recommended.
|
118
|
+
# helper Foo::BarHelper
|
91
119
|
#
|
92
|
-
# #
|
93
|
-
# helper
|
120
|
+
# # String/symbol without the "helper" suffix, camel or snake case.
|
121
|
+
# helper "Foo::Bar"
|
122
|
+
# helper :"Foo::Bar"
|
123
|
+
# helper "foo/bar"
|
124
|
+
# helper :"foo/bar"
|
125
|
+
#
|
126
|
+
# The last two assume that <tt>"foo/bar".camelize</tt> returns "Foo::Bar".
|
127
|
+
#
|
128
|
+
# The method accepts a block too. If present, the block is evaluated in
|
129
|
+
# the context of the controller helper module. This simple call makes the
|
130
|
+
# +wadus+ method available in templates of the enclosing controller:
|
94
131
|
#
|
95
|
-
# # Multi-line
|
96
132
|
# helper do
|
97
|
-
# def
|
98
|
-
# "
|
133
|
+
# def wadus
|
134
|
+
# "wadus"
|
99
135
|
# end
|
100
136
|
# end
|
101
137
|
#
|
102
|
-
#
|
103
|
-
# +symbols+, +strings+, +modules+ and blocks.
|
138
|
+
# Furthermore, all the above styles can be mixed together:
|
104
139
|
#
|
105
|
-
# helper
|
140
|
+
# helper FooHelper, "woo", "bar/baz" do
|
141
|
+
# def wadus
|
142
|
+
# "wadus"
|
143
|
+
# end
|
144
|
+
# end
|
106
145
|
#
|
107
146
|
def helper(*args, &block)
|
108
147
|
modules_for_helpers(args).each do |mod|
|
109
|
-
|
148
|
+
next if _helpers.include?(mod)
|
149
|
+
_helpers_for_modification.include(mod)
|
110
150
|
end
|
111
151
|
|
112
|
-
|
152
|
+
_helpers_for_modification.module_eval(&block) if block_given?
|
113
153
|
end
|
114
154
|
|
115
155
|
# Clears up all existing helpers in this class, only keeping the helper
|
@@ -123,72 +163,48 @@ module AbstractController
|
|
123
163
|
default_helper_module! unless anonymous?
|
124
164
|
end
|
125
165
|
|
126
|
-
#
|
127
|
-
#
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
#
|
132
|
-
# Module:: No further processing
|
133
|
-
#
|
134
|
-
# After loading the appropriate files, the corresponding modules
|
135
|
-
# are returned.
|
136
|
-
#
|
137
|
-
# ==== Parameters
|
138
|
-
# * <tt>args</tt> - An array of helpers
|
139
|
-
#
|
140
|
-
# ==== Returns
|
141
|
-
# * <tt>Array</tt> - A normalized list of modules for the list of
|
142
|
-
# helpers provided.
|
143
|
-
def modules_for_helpers(args)
|
144
|
-
args.flatten.map! do |arg|
|
145
|
-
case arg
|
146
|
-
when String, Symbol
|
147
|
-
file_name = "#{arg.to_s.underscore}_helper"
|
148
|
-
begin
|
149
|
-
require_dependency(file_name)
|
150
|
-
rescue LoadError => e
|
151
|
-
raise AbstractController::Helpers::MissingHelperError.new(e, file_name)
|
152
|
-
end
|
153
|
-
|
154
|
-
mod_name = file_name.camelize
|
155
|
-
begin
|
156
|
-
mod_name.constantize
|
157
|
-
rescue LoadError
|
158
|
-
# dependencies.rb gives a similar error message but its wording is
|
159
|
-
# not as clear because it mentions autoloading. To the user all it
|
160
|
-
# matters is that a helper module couldn't be loaded, autoloading
|
161
|
-
# is an internal mechanism that should not leak.
|
162
|
-
raise NameError, "Couldn't find #{mod_name}, expected it to be defined in helpers/#{file_name}.rb"
|
163
|
-
end
|
166
|
+
# Given an array of values like the ones accepted by +helper+, this method
|
167
|
+
# returns an array with the corresponding modules, in the same order.
|
168
|
+
def modules_for_helpers(modules_or_helper_prefixes)
|
169
|
+
modules_or_helper_prefixes.flatten.map! do |module_or_helper_prefix|
|
170
|
+
case module_or_helper_prefix
|
164
171
|
when Module
|
165
|
-
|
172
|
+
module_or_helper_prefix
|
173
|
+
when String, Symbol
|
174
|
+
helper_prefix = module_or_helper_prefix.to_s
|
175
|
+
helper_prefix = helper_prefix.camelize unless helper_prefix.start_with?(/[A-Z]/)
|
176
|
+
"#{helper_prefix}Helper".constantize
|
166
177
|
else
|
167
178
|
raise ArgumentError, "helper must be a String, Symbol, or Module"
|
168
179
|
end
|
169
180
|
end
|
170
181
|
end
|
171
182
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
# * <tt>module</tt> - The module to include into the current helper module
|
178
|
-
# for the class
|
179
|
-
def add_template_helper(mod)
|
180
|
-
_helpers.module_eval { include mod }
|
183
|
+
def _helpers_for_modification
|
184
|
+
unless @_helpers
|
185
|
+
self._helpers = define_helpers_module(self, superclass._helpers)
|
186
|
+
end
|
187
|
+
_helpers
|
181
188
|
end
|
182
189
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
190
|
+
private
|
191
|
+
def define_helpers_module(klass, helpers = nil)
|
192
|
+
# In some tests inherited is called explicitly. In that case, just
|
193
|
+
# return the module from the first time it was defined
|
194
|
+
return klass.const_get(:HelperMethods) if klass.const_defined?(:HelperMethods, false)
|
195
|
+
|
196
|
+
mod = Module.new
|
197
|
+
klass.const_set(:HelperMethods, mod)
|
198
|
+
mod.include(helpers) if helpers
|
199
|
+
mod
|
200
|
+
end
|
201
|
+
|
202
|
+
def default_helper_module!
|
203
|
+
helper_prefix = name.delete_suffix("Controller")
|
204
|
+
helper(helper_prefix)
|
205
|
+
rescue NameError => e
|
206
|
+
raise unless e.missing_name?("#{helper_prefix}Helper")
|
207
|
+
end
|
192
208
|
end
|
193
209
|
end
|
194
210
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AbstractController
|
2
4
|
module Railties
|
3
5
|
module RoutesHelpers
|
@@ -5,10 +7,26 @@ module AbstractController
|
|
5
7
|
Module.new do
|
6
8
|
define_method(:inherited) do |klass|
|
7
9
|
super(klass)
|
8
|
-
|
9
|
-
|
10
|
+
|
11
|
+
namespace = klass.module_parents.detect { |m| m.respond_to?(:railtie_routes_url_helpers) }
|
12
|
+
actual_routes = namespace ? namespace.railtie_routes_url_helpers._routes : routes
|
13
|
+
|
14
|
+
if namespace
|
15
|
+
klass.include(namespace.railtie_routes_url_helpers(include_path_helpers))
|
10
16
|
else
|
11
|
-
klass.
|
17
|
+
klass.include(routes.url_helpers(include_path_helpers))
|
18
|
+
end
|
19
|
+
|
20
|
+
# In the case that we have ex.
|
21
|
+
# class A::Foo < ApplicationController
|
22
|
+
# class Bar < A::Foo
|
23
|
+
# We will need to redefine _routes because it will not be correct
|
24
|
+
# via inheritance.
|
25
|
+
unless klass._routes.equal?(actual_routes)
|
26
|
+
klass.redefine_singleton_method(:_routes) { actual_routes }
|
27
|
+
klass.include(Module.new do
|
28
|
+
define_method(:_routes) { @_routes || actual_routes }
|
29
|
+
end)
|
12
30
|
end
|
13
31
|
end
|
14
32
|
end
|
@@ -1,8 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "abstract_controller/error"
|
4
|
+
require "action_view"
|
5
|
+
require "action_view/view_paths"
|
6
|
+
require "set"
|
6
7
|
|
7
8
|
module AbstractController
|
8
9
|
class DoubleRenderError < Error
|
@@ -17,66 +18,61 @@ module AbstractController
|
|
17
18
|
extend ActiveSupport::Concern
|
18
19
|
include ActionView::ViewPaths
|
19
20
|
|
20
|
-
#
|
21
|
-
# sticks the result in self.response_body
|
22
|
-
# :api: public
|
21
|
+
# Normalizes arguments, options and then delegates render_to_body and
|
22
|
+
# sticks the result in <tt>self.response_body</tt>.
|
23
23
|
def render(*args, &block)
|
24
24
|
options = _normalize_render(*args, &block)
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
rendered_body = render_to_body(options)
|
26
|
+
if options[:html]
|
27
|
+
_set_html_content_type
|
28
|
+
else
|
29
|
+
_set_rendered_content_type rendered_format
|
30
|
+
end
|
31
|
+
_set_vary_header
|
32
|
+
self.response_body = rendered_body
|
28
33
|
end
|
29
34
|
|
30
35
|
# Raw rendering of a template to a string.
|
31
36
|
#
|
32
37
|
# It is similar to render, except that it does not
|
33
|
-
# set the response_body and it should be guaranteed
|
38
|
+
# set the +response_body+ and it should be guaranteed
|
34
39
|
# to always return a string.
|
35
40
|
#
|
36
|
-
# If a component extends the semantics of response_body
|
37
|
-
# (as
|
41
|
+
# If a component extends the semantics of +response_body+
|
42
|
+
# (as ActionController extends it to be anything that
|
38
43
|
# responds to the method each), this method needs to be
|
39
44
|
# overridden in order to still return a string.
|
40
|
-
# :api: plugin
|
41
45
|
def render_to_string(*args, &block)
|
42
46
|
options = _normalize_render(*args, &block)
|
43
47
|
render_to_body(options)
|
44
48
|
end
|
45
49
|
|
46
50
|
# Performs the actual template rendering.
|
47
|
-
# :api: public
|
48
51
|
def render_to_body(options = {})
|
49
52
|
end
|
50
53
|
|
51
|
-
# Returns Content-Type of rendered content
|
52
|
-
# :api: public
|
54
|
+
# Returns Content-Type of rendered content.
|
53
55
|
def rendered_format
|
54
|
-
Mime
|
56
|
+
Mime[:text]
|
55
57
|
end
|
56
58
|
|
57
|
-
DEFAULT_PROTECTED_INSTANCE_VARIABLES =
|
58
|
-
@_action_name @_response_body @_formats @_prefixes @_config
|
59
|
-
@_view_context_class @_view_renderer @_lookup_context
|
60
|
-
@_routes @_db_runtime
|
61
|
-
).map(&:to_sym)
|
59
|
+
DEFAULT_PROTECTED_INSTANCE_VARIABLES = %i(@_action_name @_response_body @_formats @_prefixes)
|
62
60
|
|
63
61
|
# This method should return a hash with assigns.
|
64
62
|
# You can overwrite this configuration per controller.
|
65
|
-
# :api: public
|
66
63
|
def view_assigns
|
67
|
-
|
68
|
-
variables = instance_variables
|
64
|
+
variables = instance_variables - _protected_ivars
|
69
65
|
|
70
|
-
variables.
|
71
|
-
variables.each_with_object({}) { |name, hash|
|
66
|
+
variables.each_with_object({}) do |name, hash|
|
72
67
|
hash[name.slice(1, name.length)] = instance_variable_get(name)
|
73
|
-
|
68
|
+
end
|
74
69
|
end
|
75
70
|
|
76
|
-
|
77
|
-
#
|
78
|
-
# :
|
79
|
-
|
71
|
+
private
|
72
|
+
# Normalize args by converting <tt>render "foo"</tt> to
|
73
|
+
# <tt>render :action => "foo"</tt> and <tt>render "foo/bar"</tt> to
|
74
|
+
# <tt>render :file => "foo/bar"</tt>.
|
75
|
+
def _normalize_args(action = nil, options = {}) # :doc:
|
80
76
|
if action.respond_to?(:permitted?)
|
81
77
|
if action.permitted?
|
82
78
|
action
|
@@ -91,35 +87,40 @@ module AbstractController
|
|
91
87
|
end
|
92
88
|
|
93
89
|
# Normalize options.
|
94
|
-
# :
|
95
|
-
def _normalize_options(options)
|
90
|
+
def _normalize_options(options) # :doc:
|
96
91
|
options
|
97
92
|
end
|
98
93
|
|
99
94
|
# Process extra options.
|
100
|
-
# :
|
101
|
-
def _process_options(options)
|
95
|
+
def _process_options(options) # :doc:
|
102
96
|
options
|
103
97
|
end
|
104
98
|
|
105
99
|
# Process the rendered format.
|
106
|
-
# :
|
107
|
-
|
100
|
+
def _process_format(format) # :nodoc:
|
101
|
+
end
|
102
|
+
|
103
|
+
def _process_variant(options)
|
104
|
+
end
|
105
|
+
|
106
|
+
def _set_html_content_type # :nodoc:
|
107
|
+
end
|
108
|
+
|
109
|
+
def _set_vary_header # :nodoc:
|
110
|
+
end
|
111
|
+
|
112
|
+
def _set_rendered_content_type(format) # :nodoc:
|
108
113
|
end
|
109
114
|
|
110
115
|
# Normalize args and options.
|
111
|
-
# :
|
112
|
-
def _normalize_render(*args, &block)
|
116
|
+
def _normalize_render(*args, &block) # :nodoc:
|
113
117
|
options = _normalize_args(*args, &block)
|
114
|
-
|
115
|
-
if defined?(request) && request && request.variant.present?
|
116
|
-
options[:variant] = request.variant
|
117
|
-
end
|
118
|
+
_process_variant(options)
|
118
119
|
_normalize_options(options)
|
119
120
|
options
|
120
121
|
end
|
121
122
|
|
122
|
-
def _protected_ivars
|
123
|
+
def _protected_ivars
|
123
124
|
DEFAULT_PROTECTED_INSTANCE_VARIABLES
|
124
125
|
end
|
125
126
|
end
|
@@ -1,5 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/symbol/starts_ends_with"
|
4
|
+
|
1
5
|
module AbstractController
|
2
6
|
module Translation
|
7
|
+
mattr_accessor :raise_on_missing_translations, default: false
|
8
|
+
|
3
9
|
# Delegates to <tt>I18n.translate</tt>. Also aliased as <tt>t</tt>.
|
4
10
|
#
|
5
11
|
# When the given key starts with a period, it will be scoped by the current
|
@@ -8,20 +14,23 @@ module AbstractController
|
|
8
14
|
# <tt>I18n.translate("people.index.foo")</tt>. This makes it less repetitive
|
9
15
|
# to translate many keys within the same controller / action and gives you a
|
10
16
|
# simple framework for scoping them consistently.
|
11
|
-
def translate(
|
12
|
-
key
|
13
|
-
|
14
|
-
|
15
|
-
|
17
|
+
def translate(key, **options)
|
18
|
+
if key&.start_with?(".")
|
19
|
+
path = controller_path.tr("/", ".")
|
20
|
+
defaults = [:"#{path}#{key}"]
|
21
|
+
defaults << options[:default] if options[:default]
|
22
|
+
options[:default] = defaults.flatten
|
23
|
+
key = "#{path}.#{action_name}#{key}"
|
16
24
|
end
|
17
25
|
|
18
|
-
|
26
|
+
i18n_raise = options.fetch(:raise, self.raise_on_missing_translations)
|
27
|
+
I18n.translate(key, **options, raise: i18n_raise)
|
19
28
|
end
|
20
29
|
alias :t :translate
|
21
30
|
|
22
31
|
# Delegates to <tt>I18n.localize</tt>. Also aliased as <tt>l</tt>.
|
23
|
-
def localize(
|
24
|
-
I18n.localize(
|
32
|
+
def localize(object, **options)
|
33
|
+
I18n.localize(object, **options)
|
25
34
|
end
|
26
35
|
alias :l :localize
|
27
36
|
end
|
data/lib/abstract_controller.rb
CHANGED
@@ -1,13 +1,16 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "action_pack"
|
4
|
+
require "active_support"
|
5
|
+
require "active_support/rails"
|
6
|
+
require "active_support/i18n"
|
6
7
|
|
7
8
|
module AbstractController
|
8
9
|
extend ActiveSupport::Autoload
|
9
10
|
|
11
|
+
autoload :ActionNotFound, "abstract_controller/base"
|
10
12
|
autoload :Base
|
13
|
+
autoload :Caching
|
11
14
|
autoload :Callbacks
|
12
15
|
autoload :Collector
|
13
16
|
autoload :DoubleRenderError, "abstract_controller/rendering"
|
@@ -17,4 +20,9 @@ module AbstractController
|
|
17
20
|
autoload :Translation
|
18
21
|
autoload :AssetPaths
|
19
22
|
autoload :UrlFor
|
23
|
+
|
24
|
+
def self.eager_load!
|
25
|
+
super
|
26
|
+
AbstractController::Caching.eager_load!
|
27
|
+
end
|
20
28
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionController
|
4
|
+
module ApiRendering
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
include Rendering
|
9
|
+
end
|
10
|
+
|
11
|
+
def render_to_body(options = {})
|
12
|
+
_process_options(options)
|
13
|
+
super
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|