actionpack 7.0.4 → 7.1.3.4

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.

Files changed (140) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +397 -269
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -4
  5. data/lib/abstract_controller/base.rb +20 -11
  6. data/lib/abstract_controller/caching/fragments.rb +2 -0
  7. data/lib/abstract_controller/callbacks.rb +31 -6
  8. data/lib/abstract_controller/deprecator.rb +7 -0
  9. data/lib/abstract_controller/helpers.rb +75 -28
  10. data/lib/abstract_controller/railties/routes_helpers.rb +1 -16
  11. data/lib/abstract_controller/rendering.rb +12 -14
  12. data/lib/abstract_controller/translation.rb +9 -6
  13. data/lib/abstract_controller/url_for.rb +2 -0
  14. data/lib/abstract_controller.rb +6 -0
  15. data/lib/action_controller/api.rb +6 -4
  16. data/lib/action_controller/base.rb +3 -17
  17. data/lib/action_controller/caching.rb +2 -0
  18. data/lib/action_controller/deprecator.rb +7 -0
  19. data/lib/action_controller/form_builder.rb +2 -0
  20. data/lib/action_controller/log_subscriber.rb +16 -4
  21. data/lib/action_controller/metal/basic_implicit_render.rb +3 -1
  22. data/lib/action_controller/metal/conditional_get.rb +121 -123
  23. data/lib/action_controller/metal/content_security_policy.rb +5 -5
  24. data/lib/action_controller/metal/data_streaming.rb +20 -18
  25. data/lib/action_controller/metal/default_headers.rb +2 -0
  26. data/lib/action_controller/metal/etag_with_flash.rb +3 -1
  27. data/lib/action_controller/metal/etag_with_template_digest.rb +2 -0
  28. data/lib/action_controller/metal/exceptions.rb +8 -0
  29. data/lib/action_controller/metal/head.rb +9 -7
  30. data/lib/action_controller/metal/helpers.rb +3 -14
  31. data/lib/action_controller/metal/http_authentication.rb +17 -8
  32. data/lib/action_controller/metal/implicit_render.rb +5 -3
  33. data/lib/action_controller/metal/instrumentation.rb +8 -1
  34. data/lib/action_controller/metal/live.rb +25 -1
  35. data/lib/action_controller/metal/mime_responds.rb +2 -2
  36. data/lib/action_controller/metal/params_wrapper.rb +4 -2
  37. data/lib/action_controller/metal/permissions_policy.rb +2 -2
  38. data/lib/action_controller/metal/redirecting.rb +29 -8
  39. data/lib/action_controller/metal/renderers.rb +4 -4
  40. data/lib/action_controller/metal/rendering.rb +114 -9
  41. data/lib/action_controller/metal/request_forgery_protection.rb +144 -53
  42. data/lib/action_controller/metal/rescue.rb +6 -3
  43. data/lib/action_controller/metal/streaming.rb +71 -31
  44. data/lib/action_controller/metal/strong_parameters.rb +158 -101
  45. data/lib/action_controller/metal/url_for.rb +9 -4
  46. data/lib/action_controller/metal.rb +79 -21
  47. data/lib/action_controller/railtie.rb +24 -10
  48. data/lib/action_controller/renderer.rb +99 -85
  49. data/lib/action_controller/test_case.rb +15 -5
  50. data/lib/action_controller.rb +8 -1
  51. data/lib/action_dispatch/constants.rb +32 -0
  52. data/lib/action_dispatch/deprecator.rb +7 -0
  53. data/lib/action_dispatch/http/cache.rb +9 -11
  54. data/lib/action_dispatch/http/content_security_policy.rb +14 -9
  55. data/lib/action_dispatch/http/filter_parameters.rb +14 -28
  56. data/lib/action_dispatch/http/headers.rb +3 -1
  57. data/lib/action_dispatch/http/mime_negotiation.rb +22 -22
  58. data/lib/action_dispatch/http/mime_type.rb +35 -12
  59. data/lib/action_dispatch/http/mime_types.rb +3 -1
  60. data/lib/action_dispatch/http/parameters.rb +1 -1
  61. data/lib/action_dispatch/http/permissions_policy.rb +38 -23
  62. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  63. data/lib/action_dispatch/http/request.rb +63 -30
  64. data/lib/action_dispatch/http/response.rb +80 -63
  65. data/lib/action_dispatch/http/upload.rb +15 -2
  66. data/lib/action_dispatch/journey/formatter.rb +8 -2
  67. data/lib/action_dispatch/journey/path/pattern.rb +14 -14
  68. data/lib/action_dispatch/journey/route.rb +3 -2
  69. data/lib/action_dispatch/journey/router.rb +9 -8
  70. data/lib/action_dispatch/journey/routes.rb +2 -2
  71. data/lib/action_dispatch/log_subscriber.rb +23 -0
  72. data/lib/action_dispatch/middleware/actionable_exceptions.rb +5 -6
  73. data/lib/action_dispatch/middleware/assume_ssl.rb +24 -0
  74. data/lib/action_dispatch/middleware/callbacks.rb +2 -0
  75. data/lib/action_dispatch/middleware/cookies.rb +108 -117
  76. data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -25
  77. data/lib/action_dispatch/middleware/debug_locks.rb +4 -1
  78. data/lib/action_dispatch/middleware/debug_view.rb +7 -2
  79. data/lib/action_dispatch/middleware/exception_wrapper.rb +186 -27
  80. data/lib/action_dispatch/middleware/executor.rb +1 -1
  81. data/lib/action_dispatch/middleware/flash.rb +7 -0
  82. data/lib/action_dispatch/middleware/host_authorization.rb +18 -8
  83. data/lib/action_dispatch/middleware/public_exceptions.rb +5 -3
  84. data/lib/action_dispatch/middleware/reloader.rb +7 -5
  85. data/lib/action_dispatch/middleware/remote_ip.rb +21 -20
  86. data/lib/action_dispatch/middleware/request_id.rb +4 -2
  87. data/lib/action_dispatch/middleware/server_timing.rb +4 -4
  88. data/lib/action_dispatch/middleware/session/abstract_store.rb +5 -0
  89. data/lib/action_dispatch/middleware/session/cache_store.rb +2 -0
  90. data/lib/action_dispatch/middleware/session/cookie_store.rb +11 -5
  91. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +3 -1
  92. data/lib/action_dispatch/middleware/show_exceptions.rb +25 -18
  93. data/lib/action_dispatch/middleware/ssl.rb +18 -6
  94. data/lib/action_dispatch/middleware/stack.rb +7 -2
  95. data/lib/action_dispatch/middleware/static.rb +14 -10
  96. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +2 -2
  97. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +4 -4
  98. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +8 -1
  99. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -3
  100. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -3
  101. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +7 -7
  102. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +2 -2
  103. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +17 -0
  104. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +16 -12
  105. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -1
  106. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
  107. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +4 -4
  108. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
  109. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +1 -1
  110. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +3 -0
  111. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +59 -41
  112. data/lib/action_dispatch/railtie.rb +14 -4
  113. data/lib/action_dispatch/request/session.rb +16 -6
  114. data/lib/action_dispatch/request/utils.rb +8 -3
  115. data/lib/action_dispatch/routing/inspector.rb +54 -6
  116. data/lib/action_dispatch/routing/mapper.rb +58 -24
  117. data/lib/action_dispatch/routing/polymorphic_routes.rb +2 -0
  118. data/lib/action_dispatch/routing/redirection.rb +15 -6
  119. data/lib/action_dispatch/routing/route_set.rb +52 -22
  120. data/lib/action_dispatch/routing/routes_proxy.rb +10 -15
  121. data/lib/action_dispatch/routing/url_for.rb +26 -22
  122. data/lib/action_dispatch/routing.rb +7 -7
  123. data/lib/action_dispatch/system_test_case.rb +3 -3
  124. data/lib/action_dispatch/system_testing/browser.rb +20 -19
  125. data/lib/action_dispatch/system_testing/driver.rb +14 -22
  126. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +27 -16
  127. data/lib/action_dispatch/testing/assertion_response.rb +1 -1
  128. data/lib/action_dispatch/testing/assertions/response.rb +14 -7
  129. data/lib/action_dispatch/testing/assertions/routing.rb +67 -28
  130. data/lib/action_dispatch/testing/assertions.rb +3 -1
  131. data/lib/action_dispatch/testing/integration.rb +27 -17
  132. data/lib/action_dispatch/testing/request_encoder.rb +4 -1
  133. data/lib/action_dispatch/testing/test_process.rb +4 -3
  134. data/lib/action_dispatch/testing/test_request.rb +1 -1
  135. data/lib/action_dispatch/testing/test_response.rb +23 -9
  136. data/lib/action_dispatch.rb +37 -4
  137. data/lib/action_pack/gem_version.rb +4 -4
  138. data/lib/action_pack/version.rb +1 -1
  139. data/lib/action_pack.rb +1 -1
  140. metadata +65 -29
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2004-2022 David Heinemeier Hansson
1
+ Copyright (c) David Heinemeier Hansson
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.rdoc CHANGED
@@ -16,11 +16,11 @@ It consists of several modules:
16
16
  subclassed to implement filters and actions to handle requests. The result
17
17
  of an action is typically content generated from views.
18
18
 
19
- With the Ruby on Rails framework, users only directly interface with the
19
+ With the Ruby on \Rails framework, users only directly interface with the
20
20
  Action Controller module. Necessary Action Dispatch functionality is activated
21
21
  by default and Action View rendering is implicitly triggered by Action
22
22
  Controller. However, these modules are designed to function on their own and
23
- can be used outside of Rails.
23
+ can be used outside of \Rails.
24
24
 
25
25
  You can read more about Action Pack in the {Action Controller Overview}[https://guides.rubyonrails.org/action_controller_overview.html] guide.
26
26
 
@@ -30,7 +30,7 @@ The latest version of Action Pack can be installed with RubyGems:
30
30
 
31
31
  $ gem install actionpack
32
32
 
33
- Source code can be downloaded as part of the Rails project on GitHub:
33
+ Source code can be downloaded as part of the \Rails project on GitHub:
34
34
 
35
35
  * https://github.com/rails/rails/tree/main/actionpack
36
36
 
@@ -48,7 +48,7 @@ API documentation is at:
48
48
 
49
49
  * https://api.rubyonrails.org
50
50
 
51
- Bug reports for the Ruby on Rails project can be filed here:
51
+ Bug reports for the Ruby on \Rails project can be filed here:
52
52
 
53
53
  * https://github.com/rails/rails/issues
54
54
 
@@ -26,6 +26,8 @@ module AbstractController
26
26
  end
27
27
  end
28
28
 
29
+ # = Abstract Controller \Base
30
+ #
29
31
  # AbstractController::Base is a low-level API. Nobody should be
30
32
  # using it directly, and subclasses (like ActionController::Base) are
31
33
  # expected to provide their own +render+ method, since rendering means
@@ -70,12 +72,17 @@ module AbstractController
70
72
  # instance methods on that abstract class. Public instance methods of
71
73
  # a controller would normally be considered action methods, so methods
72
74
  # declared on abstract classes are being removed.
73
- # (<tt>ActionController::Metal</tt> and ActionController::Base are defined as abstract)
75
+ # (ActionController::Metal and ActionController::Base are defined as abstract)
74
76
  def internal_methods
75
77
  controller = self
78
+ methods = []
76
79
 
77
- controller = controller.superclass until controller.abstract?
78
- controller.public_instance_methods(true)
80
+ until controller.abstract?
81
+ methods += controller.public_instance_methods(false)
82
+ controller = controller.superclass
83
+ end
84
+
85
+ controller.public_instance_methods(true) - methods
79
86
  end
80
87
 
81
88
  # A list of method names that should be considered actions. This
@@ -89,14 +96,11 @@ module AbstractController
89
96
  def action_methods
90
97
  @action_methods ||= begin
91
98
  # All public instance methods of this class, including ancestors
92
- methods = (public_instance_methods(true) -
93
- # Except for public instance methods of Base and its ancestors
94
- internal_methods +
95
- # Be sure to include shadowed public instance methods of this class
96
- public_instance_methods(false))
97
-
99
+ # except for public instance methods of Base and its ancestors.
100
+ methods = public_instance_methods(true) - internal_methods
101
+ # Be sure to include shadowed public instance methods of this class.
102
+ methods.concat(public_instance_methods(false))
98
103
  methods.map!(&:to_s)
99
-
100
104
  methods.to_set
101
105
  end
102
106
  end
@@ -127,11 +131,16 @@ module AbstractController
127
131
  super
128
132
  clear_action_methods!
129
133
  end
134
+
135
+ def eager_load! # :nodoc:
136
+ action_methods
137
+ nil
138
+ end
130
139
  end
131
140
 
132
141
  abstract!
133
142
 
134
- # Calls the action going through the entire action dispatch stack.
143
+ # Calls the action going through the entire Action Dispatch stack.
135
144
  #
136
145
  # The actual method that is called is determined by calling
137
146
  # #method_for_action. If no method can handle the action, then an
@@ -2,6 +2,8 @@
2
2
 
3
3
  module AbstractController
4
4
  module Caching
5
+ # = Abstract Controller Caching \Fragments
6
+ #
5
7
  # Fragment caching is used for caching various blocks within
6
8
  # views without caching the entire action as a whole. This is
7
9
  # useful when certain elements of an action change frequently or
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AbstractController
4
- # = Abstract Controller Callbacks
4
+ # = Abstract Controller \Callbacks
5
5
  #
6
6
  # Abstract Controller provides hooks during the life cycle of a controller action.
7
7
  # Callbacks allow you to trigger logic during this cycle. Available callbacks are:
@@ -33,14 +33,36 @@ module AbstractController
33
33
  define_callbacks :process_action,
34
34
  terminator: ->(controller, result_lambda) { result_lambda.call; controller.performed? },
35
35
  skip_after_callbacks_if_terminated: true
36
+ mattr_accessor :raise_on_missing_callback_actions, default: false
36
37
  end
37
38
 
38
39
  class ActionFilter # :nodoc:
39
- def initialize(actions)
40
+ def initialize(filters, conditional_key, actions)
41
+ @filters = filters.to_a
42
+ @conditional_key = conditional_key
40
43
  @actions = Array(actions).map(&:to_s).to_set
41
44
  end
42
45
 
43
46
  def match?(controller)
47
+ if controller.raise_on_missing_callback_actions
48
+ missing_action = @actions.find { |action| !controller.available_action?(action) }
49
+ if missing_action
50
+ filter_names = @filters.length == 1 ? @filters.first.inspect : @filters.inspect
51
+
52
+ message = <<~MSG
53
+ The #{missing_action} action could not be found for the #{filter_names}
54
+ callback on #{controller.class.name}, but it is listed in the controller's
55
+ #{@conditional_key.inspect} option.
56
+
57
+ Raising for missing callback actions is a new default in Rails 7.1, if you'd
58
+ like to turn this off you can delete the option from the environment configurations
59
+ or set `config.action_controller.raise_on_missing_callback_actions` to `false`.
60
+ MSG
61
+
62
+ raise ActionNotFound.new(message, controller, missing_action)
63
+ end
64
+ end
65
+
44
66
  @actions.include?(controller.action_name)
45
67
  end
46
68
 
@@ -75,9 +97,10 @@ module AbstractController
75
97
  end
76
98
 
77
99
  def _normalize_callback_option(options, from, to) # :nodoc:
78
- if from = options.delete(from)
79
- from = ActionFilter.new(from)
80
- options[to] = Array(options[to]).unshift(from)
100
+ if from_value = options.delete(from)
101
+ filters = options[:filters]
102
+ from_value = ActionFilter.new(filters, from, from_value)
103
+ options[to] = Array(options[to]).unshift(from_value)
81
104
  end
82
105
  end
83
106
 
@@ -95,8 +118,10 @@ module AbstractController
95
118
  # * <tt>options</tt> - A hash of options to be used when adding the callback.
96
119
  def _insert_callbacks(callbacks, block = nil)
97
120
  options = callbacks.extract_options!
98
- _normalize_callback_options(options)
99
121
  callbacks.push(block) if block
122
+ options[:filters] = callbacks
123
+ _normalize_callback_options(options)
124
+ options.delete(:filters)
100
125
  callbacks.each do |callback|
101
126
  yield callback, options
102
127
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AbstractController
4
+ def self.deprecator # :nodoc:
5
+ @deprecator ||= ActiveSupport::Deprecation.new
6
+ end
7
+ end
@@ -5,6 +5,7 @@ require "active_support/core_ext/name_error"
5
5
 
6
6
  module AbstractController
7
7
  module Helpers
8
+ include ActiveSupport::Deprecation::DeprecatedConstantAccessor
8
9
  extend ActiveSupport::Concern
9
10
 
10
11
  included do
@@ -23,7 +24,7 @@ module AbstractController
23
24
  self._helpers = define_helpers_module(self)
24
25
  end
25
26
 
26
- class MissingHelperError < LoadError
27
+ class DeprecatedMissingHelperError < LoadError
27
28
  def initialize(error, path)
28
29
  @error = error
29
30
  @path = "helpers/#{path}.rb"
@@ -36,11 +37,46 @@ module AbstractController
36
37
  end
37
38
  end
38
39
  end
40
+ deprecate_constant "MissingHelperError", "AbstractController::Helpers::DeprecatedMissingHelperError",
41
+ message: "AbstractController::Helpers::MissingHelperError has been deprecated. If a Helper is not present, a NameError will be raised instead.",
42
+ deprecator: AbstractController.deprecator
39
43
 
40
44
  def _helpers
41
45
  self.class._helpers
42
46
  end
43
47
 
48
+ module Resolution # :nodoc:
49
+ def modules_for_helpers(modules_or_helper_prefixes)
50
+ modules_or_helper_prefixes.flatten.map! do |module_or_helper_prefix|
51
+ case module_or_helper_prefix
52
+ when Module
53
+ module_or_helper_prefix
54
+ when String, Symbol
55
+ helper_prefix = module_or_helper_prefix.to_s
56
+ helper_prefix = helper_prefix.camelize unless helper_prefix.start_with?(/[A-Z]/)
57
+ "#{helper_prefix}Helper".constantize
58
+ else
59
+ raise ArgumentError, "helper must be a String, Symbol, or Module"
60
+ end
61
+ end
62
+ end
63
+
64
+ def all_helpers_from_path(path)
65
+ helpers = Array(path).flat_map do |_path|
66
+ names = Dir["#{_path}/**/*_helper.rb"].map { |file| file[_path.to_s.size + 1..-"_helper.rb".size - 1] }
67
+ names.sort!
68
+ end
69
+ helpers.uniq!
70
+ helpers
71
+ end
72
+
73
+ def helper_modules_from_paths(paths)
74
+ modules_for_helpers(all_helpers_from_path(paths))
75
+ end
76
+ end
77
+
78
+ extend Resolution
79
+
44
80
  module ClassMethods
45
81
  # When a class is inherited, wrap its helper module in a new module.
46
82
  # This ensures that the parent class's module can be changed
@@ -55,19 +91,44 @@ module AbstractController
55
91
 
56
92
  attr_writer :_helpers
57
93
 
94
+ include Resolution
95
+
96
+ ##
97
+ # :method: modules_for_helpers
98
+ # :call-seq: modules_for_helpers(modules_or_helper_prefixes)
99
+ #
100
+ # Given an array of values like the ones accepted by +helper+, this method
101
+ # returns an array with the corresponding modules, in the same order.
102
+ #
103
+ #--
104
+ # Implemented by Resolution#modules_for_helpers.
105
+
106
+ ##
107
+ # :method: all_helpers_from_path
108
+ # :call-seq: all_helpers_from_path(path)
109
+ #
110
+ # Returns a list of helper names in a given path.
111
+ #
112
+ # ActionController::Base.all_helpers_from_path 'app/helpers'
113
+ # # => ["application", "chart", "rubygems"]
114
+ #
115
+ #--
116
+ # Implemented by Resolution#all_helpers_from_path.
117
+
58
118
  # Declare a controller method as a helper. For example, the following
59
119
  # makes the +current_user+ and +logged_in?+ controller methods available
60
120
  # to the view:
61
121
  # class ApplicationController < ActionController::Base
62
122
  # helper_method :current_user, :logged_in?
63
123
  #
64
- # def current_user
65
- # @current_user ||= User.find_by(id: session[:user])
66
- # end
124
+ # private
125
+ # def current_user
126
+ # @current_user ||= User.find_by(id: session[:user])
127
+ # end
67
128
  #
68
- # def logged_in?
69
- # current_user != nil
70
- # end
129
+ # def logged_in?
130
+ # current_user != nil
131
+ # end
71
132
  # end
72
133
  #
73
134
  # In a view:
@@ -84,10 +145,13 @@ module AbstractController
84
145
  file, line = location.path, location.lineno
85
146
 
86
147
  methods.each do |method|
87
- _helpers_for_modification.class_eval <<~ruby_eval, file, line
88
- def #{method}(*args, &block) # def current_user(*args, &block)
89
- controller.send(:'#{method}', *args, &block) # controller.send(:'current_user', *args, &block)
90
- end # end
148
+ # def current_user(*args, &block)
149
+ # controller.send(:'current_user', *args, &block)
150
+ # end
151
+ _helpers_for_modification.class_eval <<~ruby_eval.lines.map(&:strip).join(";"), file, line
152
+ def #{method}(*args, &block)
153
+ controller.send(:'#{method}', *args, &block)
154
+ end
91
155
  ruby2_keywords(:'#{method}')
92
156
  ruby_eval
93
157
  end
@@ -164,23 +228,6 @@ module AbstractController
164
228
  default_helper_module! unless anonymous?
165
229
  end
166
230
 
167
- # Given an array of values like the ones accepted by +helper+, this method
168
- # returns an array with the corresponding modules, in the same order.
169
- def modules_for_helpers(modules_or_helper_prefixes)
170
- modules_or_helper_prefixes.flatten.map! do |module_or_helper_prefix|
171
- case module_or_helper_prefix
172
- when Module
173
- module_or_helper_prefix
174
- when String, Symbol
175
- helper_prefix = module_or_helper_prefix.to_s
176
- helper_prefix = helper_prefix.camelize unless helper_prefix.start_with?(/[A-Z]/)
177
- "#{helper_prefix}Helper".constantize
178
- else
179
- raise ArgumentError, "helper must be a String, Symbol, or Module"
180
- end
181
- end
182
- end
183
-
184
231
  def _helpers_for_modification
185
232
  unless @_helpers
186
233
  self._helpers = define_helpers_module(self, superclass._helpers)
@@ -10,26 +10,11 @@ module AbstractController
10
10
  define_method(:inherited) do |klass|
11
11
  super(klass)
12
12
 
13
- namespace = klass.module_parents.detect { |m| m.respond_to?(:railtie_routes_url_helpers) }
14
- actual_routes = namespace ? namespace.railtie_routes_url_helpers._routes : routes
15
-
16
- if namespace
13
+ if namespace = klass.module_parents.detect { |m| m.respond_to?(:railtie_routes_url_helpers) }
17
14
  klass.include(namespace.railtie_routes_url_helpers(include_path_helpers))
18
15
  else
19
16
  klass.include(routes.url_helpers(include_path_helpers))
20
17
  end
21
-
22
- # In the case that we have ex.
23
- # class A::Foo < ApplicationController
24
- # class Bar < A::Foo
25
- # We will need to redefine _routes because it will not be correct
26
- # via inheritance.
27
- unless klass._routes.equal?(actual_routes)
28
- klass.redefine_singleton_method(:_routes) { actual_routes }
29
- klass.include(Module.new do
30
- define_method(:_routes) { @_routes || actual_routes }
31
- end)
32
- end
33
18
  end
34
19
  end
35
20
  end
@@ -7,7 +7,7 @@ require "set"
7
7
 
8
8
  module AbstractController
9
9
  class DoubleRenderError < Error
10
- DEFAULT_MESSAGE = "Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like \"redirect_to(...) and return\"."
10
+ DEFAULT_MESSAGE = "Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like \"redirect_to(...); return\"."
11
11
 
12
12
  def initialize(message = nil)
13
13
  super(message || DEFAULT_MESSAGE)
@@ -18,8 +18,10 @@ module AbstractController
18
18
  extend ActiveSupport::Concern
19
19
  include ActionView::ViewPaths
20
20
 
21
- # Normalizes arguments, options and then delegates render_to_body and
21
+ # Normalizes arguments and options, and then delegates to render_to_body and
22
22
  # sticks the result in <tt>self.response_body</tt>.
23
+ #
24
+ # Supported options depend on the underlying +render_to_body+ implementation.
23
25
  def render(*args, &block)
24
26
  options = _normalize_render(*args, &block)
25
27
  rendered_body = render_to_body(options)
@@ -32,16 +34,12 @@ module AbstractController
32
34
  self.response_body = rendered_body
33
35
  end
34
36
 
35
- # Raw rendering of a template to a string.
36
- #
37
- # It is similar to render, except that it does not
38
- # set the +response_body+ and it should be guaranteed
39
- # to always return a string.
37
+ # Similar to #render, but only returns the rendered template as a string,
38
+ # instead of setting +self.response_body+.
40
39
  #
41
- # If a component extends the semantics of +response_body+
42
- # (as ActionController extends it to be anything that
43
- # responds to the method each), this method needs to be
44
- # overridden in order to still return a string.
40
+ # If a component extends the semantics of +response_body+ (as ActionController
41
+ # extends it to be anything that responds to the method each), this method
42
+ # needs to be overridden in order to still return a string.
45
43
  def render_to_string(*args, &block)
46
44
  options = _normalize_render(*args, &block)
47
45
  render_to_body(options)
@@ -51,7 +49,7 @@ module AbstractController
51
49
  def render_to_body(options = {})
52
50
  end
53
51
 
54
- # Returns Content-Type of rendered content.
52
+ # Returns +Content-Type+ of rendered content.
55
53
  def rendered_format
56
54
  Mime[:text]
57
55
  end
@@ -70,8 +68,8 @@ module AbstractController
70
68
 
71
69
  private
72
70
  # 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>.
71
+ # <tt>render action: "foo"</tt> and <tt>render "foo/bar"</tt> to
72
+ # <tt>render file: "foo/bar"</tt>.
75
73
  def _normalize_args(action = nil, options = {}) # :doc:
76
74
  if action.respond_to?(:permitted?)
77
75
  if action.permitted?
@@ -4,9 +4,7 @@ require "active_support/html_safe_translation"
4
4
 
5
5
  module AbstractController
6
6
  module Translation
7
- mattr_accessor :raise_on_missing_translations, default: false
8
-
9
- # Delegates to <tt>I18n.translate</tt>. Also aliased as <tt>t</tt>.
7
+ # Delegates to <tt>I18n.translate</tt>.
10
8
  #
11
9
  # When the given key starts with a period, it will be scoped by the current
12
10
  # controller and action. So if you call <tt>translate(".foo")</tt> from
@@ -23,13 +21,18 @@ module AbstractController
23
21
  key = "#{path}.#{action_name}#{key}"
24
22
  end
25
23
 
26
- i18n_raise = options.fetch(:raise, self.raise_on_missing_translations)
24
+ if options[:default]
25
+ options[:default] = [options[:default]] unless options[:default].is_a?(Array)
26
+ options[:default] = options[:default].map do |value|
27
+ value.is_a?(String) ? ERB::Util.html_escape(value) : value
28
+ end
29
+ end
27
30
 
28
- ActiveSupport::HtmlSafeTranslation.translate(key, **options, raise: i18n_raise)
31
+ ActiveSupport::HtmlSafeTranslation.translate(key, **options)
29
32
  end
30
33
  alias :t :translate
31
34
 
32
- # Delegates to <tt>I18n.localize</tt>. Also aliased as <tt>l</tt>.
35
+ # Delegates to <tt>I18n.localize</tt>.
33
36
  def localize(object, **options)
34
37
  I18n.localize(object, **options)
35
38
  end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AbstractController
4
+ # = URL For
5
+ #
4
6
  # Includes +url_for+ into the host class (e.g. an abstract controller or mailer). The class
5
7
  # has to provide a +RouteSet+ by implementing the <tt>_routes</tt> methods. Otherwise, an
6
8
  # exception will be raised.
@@ -4,6 +4,7 @@ require "action_pack"
4
4
  require "active_support"
5
5
  require "active_support/rails"
6
6
  require "active_support/i18n"
7
+ require "abstract_controller/deprecator"
7
8
 
8
9
  module AbstractController
9
10
  extend ActiveSupport::Autoload
@@ -24,5 +25,10 @@ module AbstractController
24
25
  def self.eager_load!
25
26
  super
26
27
  AbstractController::Caching.eager_load!
28
+ AbstractController::Base.descendants.each do |controller|
29
+ unless controller.abstract?
30
+ controller.eager_load!
31
+ end
32
+ end
27
33
  end
28
34
  end
@@ -5,6 +5,8 @@ require "action_controller"
5
5
  require "action_controller/log_subscriber"
6
6
 
7
7
  module ActionController
8
+ # = Action Controller \API
9
+ #
8
10
  # API Controller is a lightweight version of ActionController::Base,
9
11
  # created for applications that don't require all functionalities that a complete
10
12
  # \Rails controller provides, allowing you to create controllers with just the
@@ -19,7 +21,7 @@ module ActionController
19
21
  # your application, they're just not part of the default API controller stack.
20
22
  #
21
23
  # Normally, +ApplicationController+ is the only controller that inherits from
22
- # <tt>ActionController::API</tt>. All other controllers in turn inherit from
24
+ # +ActionController::API+. All other controllers in turn inherit from
23
25
  # +ApplicationController+.
24
26
  #
25
27
  # A sample controller could look like this:
@@ -40,7 +42,7 @@ module ActionController
40
42
  # can use <tt>render :json</tt> and siblings freely in your controllers. Keep
41
43
  # in mind that templates are not going to be rendered, so you need to ensure
42
44
  # your controller is calling either <tt>render</tt> or <tt>redirect_to</tt> in
43
- # all actions, otherwise it will return 204 No Content.
45
+ # all actions, otherwise it will return <tt>204 No Content</tt>.
44
46
  #
45
47
  # def show
46
48
  # post = Post.find(params[:id])
@@ -62,7 +64,7 @@ module ActionController
62
64
  #
63
65
  # In some scenarios you may want to add back some functionality provided by
64
66
  # ActionController::Base that is not present by default in
65
- # <tt>ActionController::API</tt>, for instance <tt>MimeResponds</tt>. This
67
+ # +ActionController::API+, for instance <tt>MimeResponds</tt>. This
66
68
  # module gives you the <tt>respond_to</tt> method. Adding it is quite simple,
67
69
  # you just need to include the module in a specific controller or in
68
70
  # +ApplicationController+ in case you want it available in your entire
@@ -85,7 +87,7 @@ module ActionController
85
87
  #
86
88
  # Make sure to check the modules included in ActionController::Base
87
89
  # if you want to use any other functionality that is not provided
88
- # by <tt>ActionController::API</tt> out of the box.
90
+ # by +ActionController::API+ out of the box.
89
91
  class API < Metal
90
92
  abstract!
91
93
 
@@ -5,11 +5,13 @@ require "action_controller/log_subscriber"
5
5
  require "action_controller/metal/params_wrapper"
6
6
 
7
7
  module ActionController
8
+ # = Action Controller \Base
9
+ #
8
10
  # Action Controllers are the core of a web request in \Rails. They are made up of one or more actions that are executed
9
11
  # on request and then either it renders a template or redirects to another action. An action is defined as a public method
10
12
  # on the controller, which will automatically be made accessible to the web-server through \Rails Routes.
11
13
  #
12
- # By default, only the ApplicationController in a \Rails application inherits from <tt>ActionController::Base</tt>. All other
14
+ # By default, only the ApplicationController in a \Rails application inherits from +ActionController::Base+. All other
13
15
  # controllers inherit from ApplicationController. This gives you one class to configure things such as
14
16
  # request forgery protection and filtering of sensitive request parameters.
15
17
  #
@@ -167,22 +169,6 @@ module ActionController
167
169
  class Base < Metal
168
170
  abstract!
169
171
 
170
- # We document the request and response methods here because albeit they are
171
- # implemented in ActionController::Metal, the type of the returned objects
172
- # is unknown at that level.
173
-
174
- ##
175
- # :method: request
176
- #
177
- # Returns an ActionDispatch::Request instance that represents the
178
- # current request.
179
-
180
- ##
181
- # :method: response
182
- #
183
- # Returns an ActionDispatch::Response that represents the current
184
- # response.
185
-
186
172
  # Shortcut helper that returns all the modules included in
187
173
  # ActionController::Base except the ones passed as arguments:
188
174
  #
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionController
4
+ # = Action Controller \Caching
5
+ #
4
6
  # \Caching is a cheap way of speeding up slow applications by keeping the result of
5
7
  # calculations, renderings, and database calls around for subsequent requests.
6
8
  #
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionController
4
+ def self.deprecator # :nodoc:
5
+ AbstractController.deprecator
6
+ end
7
+ end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionController
4
+ # = Action Controller Form Builder
5
+ #
4
6
  # Override the default form builder for all views rendered by this
5
7
  # controller and any of its descendants. Accepts a subclass of
6
8
  # ActionView::Helpers::FormBuilder.