actionpack 4.2.11.3 → 5.0.7.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 +4 -4
- data/CHANGELOG.md +890 -384
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -3
- data/lib/abstract_controller/base.rb +28 -38
- data/lib/{action_controller → abstract_controller}/caching/fragments.rb +51 -11
- data/lib/abstract_controller/caching.rb +62 -0
- data/lib/abstract_controller/callbacks.rb +54 -19
- data/lib/abstract_controller/collector.rb +4 -9
- data/lib/abstract_controller/error.rb +4 -0
- data/lib/abstract_controller/helpers.rb +4 -3
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -2
- data/lib/abstract_controller/rendering.rb +28 -18
- data/lib/abstract_controller/translation.rb +8 -7
- data/lib/abstract_controller.rb +6 -2
- data/lib/action_controller/api/api_rendering.rb +14 -0
- data/lib/action_controller/api.rb +147 -0
- data/lib/action_controller/base.rb +14 -11
- data/lib/action_controller/caching.rb +13 -58
- data/lib/action_controller/form_builder.rb +48 -0
- data/lib/action_controller/log_subscriber.rb +3 -10
- data/lib/action_controller/metal/basic_implicit_render.rb +11 -0
- data/lib/action_controller/metal/conditional_get.rb +106 -34
- data/lib/action_controller/metal/cookies.rb +1 -3
- data/lib/action_controller/metal/data_streaming.rb +14 -34
- data/lib/action_controller/metal/etag_with_template_digest.rb +8 -2
- data/lib/action_controller/metal/exceptions.rb +11 -6
- data/lib/action_controller/metal/force_ssl.rb +11 -11
- data/lib/action_controller/metal/head.rb +14 -8
- data/lib/action_controller/metal/helpers.rb +15 -6
- data/lib/action_controller/metal/http_authentication.rb +44 -35
- data/lib/action_controller/metal/implicit_render.rb +61 -6
- data/lib/action_controller/metal/instrumentation.rb +5 -5
- data/lib/action_controller/metal/live.rb +71 -88
- data/lib/action_controller/metal/mime_responds.rb +27 -42
- data/lib/action_controller/metal/params_wrapper.rb +9 -9
- data/lib/action_controller/metal/redirecting.rb +32 -9
- data/lib/action_controller/metal/renderers.rb +83 -40
- data/lib/action_controller/metal/rendering.rb +38 -6
- data/lib/action_controller/metal/request_forgery_protection.rb +126 -48
- data/lib/action_controller/metal/rescue.rb +3 -12
- data/lib/action_controller/metal/streaming.rb +4 -4
- data/lib/action_controller/metal/strong_parameters.rb +527 -134
- data/lib/action_controller/metal/testing.rb +1 -12
- data/lib/action_controller/metal/url_for.rb +12 -5
- data/lib/action_controller/metal.rb +88 -63
- data/lib/action_controller/railtie.rb +11 -7
- data/lib/action_controller/renderer.rb +113 -0
- data/lib/action_controller/template_assertions.rb +9 -0
- data/lib/action_controller/test_case.rb +311 -374
- data/lib/action_controller.rb +12 -9
- data/lib/action_dispatch/http/cache.rb +73 -34
- data/lib/action_dispatch/http/filter_parameters.rb +16 -12
- data/lib/action_dispatch/http/filter_redirect.rb +7 -8
- data/lib/action_dispatch/http/headers.rb +45 -14
- data/lib/action_dispatch/http/mime_negotiation.rb +42 -23
- data/lib/action_dispatch/http/mime_type.rb +126 -90
- data/lib/action_dispatch/http/mime_types.rb +3 -4
- data/lib/action_dispatch/http/parameter_filter.rb +19 -9
- data/lib/action_dispatch/http/parameters.rb +70 -40
- data/lib/action_dispatch/http/request.rb +144 -89
- data/lib/action_dispatch/http/response.rb +215 -102
- data/lib/action_dispatch/http/upload.rb +6 -2
- data/lib/action_dispatch/http/url.rb +117 -8
- data/lib/action_dispatch/journey/formatter.rb +47 -30
- data/lib/action_dispatch/journey/gtg/transition_table.rb +1 -1
- data/lib/action_dispatch/journey/nfa/dot.rb +0 -2
- data/lib/action_dispatch/journey/nfa/transition_table.rb +1 -46
- data/lib/action_dispatch/journey/nodes/node.rb +14 -4
- data/lib/action_dispatch/journey/parser.rb +2 -0
- data/lib/action_dispatch/journey/parser_extras.rb +8 -2
- data/lib/action_dispatch/journey/path/pattern.rb +38 -42
- data/lib/action_dispatch/journey/route.rb +88 -26
- data/lib/action_dispatch/journey/router/utils.rb +5 -5
- data/lib/action_dispatch/journey/router.rb +8 -10
- data/lib/action_dispatch/journey/routes.rb +14 -15
- data/lib/action_dispatch/journey/visitors.rb +89 -44
- data/lib/action_dispatch/middleware/callbacks.rb +10 -1
- data/lib/action_dispatch/middleware/cookies.rb +188 -134
- data/lib/action_dispatch/middleware/debug_exceptions.rb +128 -49
- data/lib/action_dispatch/middleware/debug_locks.rb +122 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +21 -21
- data/lib/action_dispatch/middleware/executor.rb +19 -0
- data/lib/action_dispatch/middleware/flash.rb +66 -45
- data/lib/action_dispatch/middleware/params_parser.rb +32 -46
- data/lib/action_dispatch/middleware/public_exceptions.rb +2 -2
- data/lib/action_dispatch/middleware/reloader.rb +14 -58
- data/lib/action_dispatch/middleware/remote_ip.rb +29 -19
- data/lib/action_dispatch/middleware/request_id.rb +11 -6
- data/lib/action_dispatch/middleware/session/abstract_store.rb +23 -11
- data/lib/action_dispatch/middleware/session/cache_store.rb +9 -6
- data/lib/action_dispatch/middleware/session/cookie_store.rb +30 -24
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +4 -0
- data/lib/action_dispatch/middleware/show_exceptions.rb +11 -9
- data/lib/action_dispatch/middleware/ssl.rb +124 -36
- data/lib/action_dispatch/middleware/stack.rb +44 -40
- data/lib/action_dispatch/middleware/static.rb +51 -35
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +2 -14
- data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/template_error.text.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 +59 -63
- data/lib/action_dispatch/railtie.rb +2 -2
- data/lib/action_dispatch/request/session.rb +69 -33
- data/lib/action_dispatch/request/utils.rb +51 -19
- data/lib/action_dispatch/routing/inspector.rb +32 -43
- data/lib/action_dispatch/routing/mapper.rb +515 -348
- data/lib/action_dispatch/routing/polymorphic_routes.rb +8 -14
- data/lib/action_dispatch/routing/redirection.rb +5 -4
- data/lib/action_dispatch/routing/route_set.rb +148 -240
- data/lib/action_dispatch/routing/url_for.rb +27 -10
- data/lib/action_dispatch/routing.rb +17 -13
- data/lib/action_dispatch/testing/assertion_response.rb +45 -0
- data/lib/action_dispatch/testing/assertions/response.rb +38 -20
- data/lib/action_dispatch/testing/assertions/routing.rb +16 -12
- data/lib/action_dispatch/testing/assertions.rb +1 -1
- data/lib/action_dispatch/testing/integration.rb +377 -149
- data/lib/action_dispatch/testing/request_encoder.rb +53 -0
- data/lib/action_dispatch/testing/test_process.rb +24 -20
- data/lib/action_dispatch/testing/test_request.rb +22 -31
- data/lib/action_dispatch/testing/test_response.rb +12 -4
- data/lib/action_dispatch.rb +4 -1
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack.rb +1 -1
- metadata +32 -34
- 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/journey/backwards.rb +0 -5
- data/lib/action_dispatch/journey/router/strexp.rb +0 -27
- 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
- /data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +0 -0
data/MIT-LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -28,11 +28,11 @@ can be used outside of Rails.
|
|
28
28
|
|
29
29
|
The latest version of Action Pack can be installed with RubyGems:
|
30
30
|
|
31
|
-
|
31
|
+
$ gem install actionpack
|
32
32
|
|
33
33
|
Source code can be downloaded as part of the Rails project on GitHub
|
34
34
|
|
35
|
-
* https://github.com/rails/rails/tree/
|
35
|
+
* https://github.com/rails/rails/tree/5-0-stable/actionpack
|
36
36
|
|
37
37
|
|
38
38
|
== License
|
@@ -55,4 +55,3 @@ Bug reports can be filed for the Ruby on Rails project here:
|
|
55
55
|
Feature requests should be discussed on the rails-core mailing list here:
|
56
56
|
|
57
57
|
* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core
|
58
|
-
|
@@ -1,18 +1,16 @@
|
|
1
1
|
require 'erubis'
|
2
|
-
require '
|
2
|
+
require 'abstract_controller/error'
|
3
3
|
require 'active_support/configurable'
|
4
4
|
require 'active_support/descendants_tracker'
|
5
5
|
require 'active_support/core_ext/module/anonymous'
|
6
|
+
require 'active_support/core_ext/module/attr_internal'
|
6
7
|
|
7
8
|
module AbstractController
|
8
|
-
class Error < StandardError #:nodoc:
|
9
|
-
end
|
10
|
-
|
11
9
|
# Raised when a non-existing controller action is triggered.
|
12
10
|
class ActionNotFound < StandardError
|
13
11
|
end
|
14
12
|
|
15
|
-
#
|
13
|
+
# AbstractController::Base is a low-level API. Nobody should be
|
16
14
|
# using it directly, and subclasses (like ActionController::Base) are
|
17
15
|
# expected to provide their own +render+ method, since rendering means
|
18
16
|
# different things depending on the context.
|
@@ -49,7 +47,7 @@ module AbstractController
|
|
49
47
|
# instance methods on that abstract class. Public instance methods of
|
50
48
|
# a controller would normally be considered action methods, so methods
|
51
49
|
# declared on abstract classes are being removed.
|
52
|
-
# (ActionController::Metal and ActionController::Base are defined as abstract)
|
50
|
+
# (<tt>ActionController::Metal</tt> and ActionController::Base are defined as abstract)
|
53
51
|
def internal_methods
|
54
52
|
controller = self
|
55
53
|
|
@@ -57,21 +55,11 @@ module AbstractController
|
|
57
55
|
controller.public_instance_methods(true)
|
58
56
|
end
|
59
57
|
|
60
|
-
# The list of hidden actions. Defaults to an empty array.
|
61
|
-
# This can be modified by other modules or subclasses
|
62
|
-
# to specify particular actions as hidden.
|
63
|
-
#
|
64
|
-
# ==== Returns
|
65
|
-
# * <tt>Array</tt> - An array of method names that should not be considered actions.
|
66
|
-
def hidden_actions
|
67
|
-
[]
|
68
|
-
end
|
69
|
-
|
70
58
|
# A list of method names that should be considered actions. This
|
71
59
|
# includes all public instance methods on a controller, less
|
72
|
-
# any internal methods (see
|
60
|
+
# any internal methods (see internal_methods), adding back in
|
73
61
|
# any methods that are internal, but still exist on the class
|
74
|
-
# itself.
|
62
|
+
# itself.
|
75
63
|
#
|
76
64
|
# ==== Returns
|
77
65
|
# * <tt>Set</tt> - A set of all methods that should be considered actions.
|
@@ -82,30 +70,31 @@ module AbstractController
|
|
82
70
|
# Except for public instance methods of Base and its ancestors
|
83
71
|
internal_methods +
|
84
72
|
# Be sure to include shadowed public instance methods of this class
|
85
|
-
public_instance_methods(false)).uniq.map
|
86
|
-
# And always exclude explicitly hidden actions
|
87
|
-
hidden_actions.to_a
|
73
|
+
public_instance_methods(false)).uniq.map(&:to_s)
|
88
74
|
|
89
|
-
|
90
|
-
Set.new(methods.reject { |method| method =~ /_one_time_conditions/ })
|
75
|
+
methods.to_set
|
91
76
|
end
|
92
77
|
end
|
93
78
|
|
94
|
-
# action_methods are cached and there is sometimes need to refresh
|
95
|
-
# them. clear_action_methods! allows you to do that, so next time
|
96
|
-
# you run action_methods, they will be recalculated
|
79
|
+
# action_methods are cached and there is sometimes a need to refresh
|
80
|
+
# them. ::clear_action_methods! allows you to do that, so next time
|
81
|
+
# you run action_methods, they will be recalculated.
|
97
82
|
def clear_action_methods!
|
98
83
|
@action_methods = nil
|
99
84
|
end
|
100
85
|
|
101
86
|
# Returns the full controller name, underscored, without the ending Controller.
|
102
|
-
#
|
103
|
-
#
|
87
|
+
#
|
88
|
+
# class MyApp::MyPostsController < AbstractController::Base
|
89
|
+
#
|
90
|
+
# end
|
91
|
+
#
|
92
|
+
# MyApp::MyPostsController.controller_path # => "my_app/my_posts"
|
104
93
|
#
|
105
94
|
# ==== Returns
|
106
95
|
# * <tt>String</tt>
|
107
96
|
def controller_path
|
108
|
-
@controller_path ||= name.sub(/Controller$/, '').underscore unless anonymous?
|
97
|
+
@controller_path ||= name.sub(/Controller$/, ''.freeze).underscore unless anonymous?
|
109
98
|
end
|
110
99
|
|
111
100
|
# Refresh the cached action_methods when a new action_method is added.
|
@@ -137,12 +126,12 @@ module AbstractController
|
|
137
126
|
process_action(action_name, *args)
|
138
127
|
end
|
139
128
|
|
140
|
-
# Delegates to the class'
|
129
|
+
# Delegates to the class' ::controller_path
|
141
130
|
def controller_path
|
142
131
|
self.class.controller_path
|
143
132
|
end
|
144
133
|
|
145
|
-
# Delegates to the class'
|
134
|
+
# Delegates to the class' ::action_methods
|
146
135
|
def action_methods
|
147
136
|
self.class.action_methods
|
148
137
|
end
|
@@ -157,11 +146,15 @@ module AbstractController
|
|
157
146
|
#
|
158
147
|
# ==== Parameters
|
159
148
|
# * <tt>action_name</tt> - The name of an action to be tested
|
160
|
-
#
|
161
|
-
# ==== Returns
|
162
|
-
# * <tt>TrueClass</tt>, <tt>FalseClass</tt>
|
163
149
|
def available_action?(action_name)
|
164
|
-
_find_action_name(action_name)
|
150
|
+
_find_action_name(action_name)
|
151
|
+
end
|
152
|
+
|
153
|
+
# Tests if a response body is set. Used to determine if the
|
154
|
+
# +process_action+ callback needs to be terminated in
|
155
|
+
# +AbstractController::Callbacks+.
|
156
|
+
def performed?
|
157
|
+
response_body
|
165
158
|
end
|
166
159
|
|
167
160
|
# Returns true if the given controller is capable of rendering
|
@@ -180,9 +173,6 @@ module AbstractController
|
|
180
173
|
# ==== Parameters
|
181
174
|
# * <tt>name</tt> - The name of an action to be tested
|
182
175
|
#
|
183
|
-
# ==== Returns
|
184
|
-
# * <tt>TrueClass</tt>, <tt>FalseClass</tt>
|
185
|
-
#
|
186
176
|
# :api: private
|
187
177
|
def action_method?(name)
|
188
178
|
self.class.action_methods.include?(name)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module AbstractController
|
2
2
|
module Caching
|
3
3
|
# Fragment caching is used for caching various blocks within
|
4
4
|
# views without caching the entire action as a whole. This is
|
@@ -14,12 +14,57 @@ module ActionController
|
|
14
14
|
#
|
15
15
|
# expire_fragment('name_of_cache')
|
16
16
|
module Fragments
|
17
|
+
extend ActiveSupport::Concern
|
18
|
+
|
19
|
+
included do
|
20
|
+
if respond_to?(:class_attribute)
|
21
|
+
class_attribute :fragment_cache_keys
|
22
|
+
else
|
23
|
+
mattr_writer :fragment_cache_keys
|
24
|
+
end
|
25
|
+
|
26
|
+
self.fragment_cache_keys = []
|
27
|
+
|
28
|
+
helper_method :fragment_cache_key if respond_to?(:helper_method)
|
29
|
+
end
|
30
|
+
|
31
|
+
module ClassMethods
|
32
|
+
# Allows you to specify controller-wide key prefixes for
|
33
|
+
# cache fragments. Pass either a constant +value+, or a block
|
34
|
+
# which computes a value each time a cache key is generated.
|
35
|
+
#
|
36
|
+
# For example, you may want to prefix all fragment cache keys
|
37
|
+
# with a global version identifier, so you can easily
|
38
|
+
# invalidate all caches.
|
39
|
+
#
|
40
|
+
# class ApplicationController
|
41
|
+
# fragment_cache_key "v1"
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# When it's time to invalidate all fragments, simply change
|
45
|
+
# the string constant. Or, progressively roll out the cache
|
46
|
+
# invalidation using a computed value:
|
47
|
+
#
|
48
|
+
# class ApplicationController
|
49
|
+
# fragment_cache_key do
|
50
|
+
# @account.id.odd? ? "v1" : "v2"
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
def fragment_cache_key(value = nil, &key)
|
54
|
+
self.fragment_cache_keys += [key || ->{ value }]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
17
58
|
# Given a key (as described in +expire_fragment+), returns
|
18
59
|
# a key suitable for use in reading, writing, or expiring a
|
19
|
-
# cached fragment. All keys
|
20
|
-
#
|
60
|
+
# cached fragment. All keys begin with <tt>views/</tt>,
|
61
|
+
# followed by any controller-wide key prefix values, ending
|
62
|
+
# with the specified +key+ value. The key is expanded using
|
63
|
+
# ActiveSupport::Cache.expand_cache_key.
|
21
64
|
def fragment_cache_key(key)
|
22
|
-
|
65
|
+
head = self.class.fragment_cache_keys.map { |k| instance_exec(&k) }
|
66
|
+
tail = key.is_a?(Hash) ? url_for(key).split("://").last : key
|
67
|
+
ActiveSupport::Cache.expand_cache_key([*head, *tail], :views)
|
23
68
|
end
|
24
69
|
|
25
70
|
# Writes +content+ to the location signified by
|
@@ -90,13 +135,8 @@ module ActionController
|
|
90
135
|
end
|
91
136
|
|
92
137
|
def instrument_fragment_cache(name, key) # :nodoc:
|
93
|
-
payload =
|
94
|
-
|
95
|
-
action: action_name,
|
96
|
-
key: key
|
97
|
-
}
|
98
|
-
|
99
|
-
ActiveSupport::Notifications.instrument("#{name}.action_controller", payload) { yield }
|
138
|
+
payload = instrument_payload(key)
|
139
|
+
ActiveSupport::Notifications.instrument("#{name}.#{instrument_name}", payload) { yield }
|
100
140
|
end
|
101
141
|
end
|
102
142
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module AbstractController
|
2
|
+
module Caching
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
extend ActiveSupport::Autoload
|
5
|
+
|
6
|
+
eager_autoload do
|
7
|
+
autoload :Fragments
|
8
|
+
end
|
9
|
+
|
10
|
+
module ConfigMethods
|
11
|
+
def cache_store
|
12
|
+
config.cache_store
|
13
|
+
end
|
14
|
+
|
15
|
+
def cache_store=(store)
|
16
|
+
config.cache_store = ActiveSupport::Cache.lookup_store(store)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def cache_configured?
|
21
|
+
perform_caching && cache_store
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
include ConfigMethods
|
26
|
+
include AbstractController::Caching::Fragments
|
27
|
+
|
28
|
+
included do
|
29
|
+
extend ConfigMethods
|
30
|
+
|
31
|
+
config_accessor :default_static_extension
|
32
|
+
self.default_static_extension ||= '.html'
|
33
|
+
|
34
|
+
config_accessor :perform_caching
|
35
|
+
self.perform_caching = true if perform_caching.nil?
|
36
|
+
|
37
|
+
class_attribute :_view_cache_dependencies
|
38
|
+
self._view_cache_dependencies = []
|
39
|
+
helper_method :view_cache_dependencies if respond_to?(:helper_method)
|
40
|
+
end
|
41
|
+
|
42
|
+
module ClassMethods
|
43
|
+
def view_cache_dependency(&dependency)
|
44
|
+
self._view_cache_dependencies += [dependency]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def view_cache_dependencies
|
49
|
+
self.class._view_cache_dependencies.map { |dep| instance_exec(&dep) }.compact
|
50
|
+
end
|
51
|
+
|
52
|
+
protected
|
53
|
+
# Convenience accessor.
|
54
|
+
def cache(key, options = {}, &block)
|
55
|
+
if cache_configured?
|
56
|
+
cache_store.fetch(ActiveSupport::Cache.expand_cache_key(key, :controller), options, &block)
|
57
|
+
else
|
58
|
+
yield
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -9,7 +9,7 @@ module AbstractController
|
|
9
9
|
|
10
10
|
included do
|
11
11
|
define_callbacks :process_action,
|
12
|
-
terminator: ->(controller,
|
12
|
+
terminator: ->(controller, result_lambda) { result_lambda.call if result_lambda.is_a?(Proc); controller.performed? },
|
13
13
|
skip_after_callbacks_if_terminated: true
|
14
14
|
end
|
15
15
|
|
@@ -22,14 +22,25 @@ module AbstractController
|
|
22
22
|
end
|
23
23
|
|
24
24
|
module ClassMethods
|
25
|
-
# If
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
25
|
+
# If +:only+ or +:except+ are used, convert the options into the
|
26
|
+
# +:if+ and +:unless+ options of ActiveSupport::Callbacks.
|
27
|
+
#
|
28
|
+
# The basic idea is that <tt>:only => :index</tt> gets converted to
|
29
|
+
# <tt>:if => proc {|c| c.action_name == "index" }</tt>.
|
30
|
+
#
|
31
|
+
# Note that <tt>:only</tt> has priority over <tt>:if</tt> in case they
|
32
|
+
# are used together.
|
33
|
+
#
|
34
|
+
# only: :index, if: -> { true } # the :if option will be ignored.
|
35
|
+
#
|
36
|
+
# Note that <tt>:if</tt> has priority over <tt>:except</tt> in case they
|
37
|
+
# are used together.
|
38
|
+
#
|
39
|
+
# except: :index, if: -> { true } # the :except option will be ignored.
|
29
40
|
#
|
30
41
|
# ==== Options
|
31
|
-
# * <tt>only</tt> - The callback should be run only for this action
|
32
|
-
# * <tt>except</tt> - The callback should be run for all actions except this action
|
42
|
+
# * <tt>only</tt> - The callback should be run only for this action.
|
43
|
+
# * <tt>except</tt> - The callback should be run for all actions except this action.
|
33
44
|
def _normalize_callback_options(options)
|
34
45
|
_normalize_callback_option(options, :only, :if)
|
35
46
|
_normalize_callback_option(options, :except, :unless)
|
@@ -37,7 +48,8 @@ module AbstractController
|
|
37
48
|
|
38
49
|
def _normalize_callback_option(options, from, to) # :nodoc:
|
39
50
|
if from = options[from]
|
40
|
-
|
51
|
+
_from = Array(from).map(&:to_s).to_set
|
52
|
+
from = proc {|c| _from.include? c.action_name }
|
41
53
|
options[to] = Array(options[to]).unshift(from)
|
42
54
|
end
|
43
55
|
end
|
@@ -48,13 +60,20 @@ module AbstractController
|
|
48
60
|
# * <tt>names</tt> - A list of valid names that could be used for
|
49
61
|
# callbacks. Note that skipping uses Ruby equality, so it's
|
50
62
|
# impossible to skip a callback defined using an anonymous proc
|
51
|
-
# using #skip_action_callback
|
63
|
+
# using #skip_action_callback.
|
52
64
|
def skip_action_callback(*names)
|
53
|
-
skip_before_action
|
54
|
-
|
55
|
-
|
65
|
+
ActiveSupport::Deprecation.warn('`skip_action_callback` is deprecated and will be removed in Rails 5.1. Please use skip_before_action, skip_after_action or skip_around_action instead.')
|
66
|
+
skip_before_action(*names, raise: false)
|
67
|
+
skip_after_action(*names, raise: false)
|
68
|
+
skip_around_action(*names, raise: false)
|
69
|
+
end
|
70
|
+
|
71
|
+
def skip_filter(*names)
|
72
|
+
ActiveSupport::Deprecation.warn("`skip_filter` is deprecated and will be removed in Rails 5.1. Use skip_before_action, skip_after_action or skip_around_action instead.")
|
73
|
+
skip_before_action(*names, raise: false)
|
74
|
+
skip_after_action(*names, raise: false)
|
75
|
+
skip_around_action(*names, raise: false)
|
56
76
|
end
|
57
|
-
alias_method :skip_filter, :skip_action_callback
|
58
77
|
|
59
78
|
# Take callback names and an optional callback proc, normalize them,
|
60
79
|
# then call the block with each callback. This allows us to abstract
|
@@ -66,8 +85,8 @@ module AbstractController
|
|
66
85
|
# * <tt>block</tt> - A proc that should be added to the callbacks.
|
67
86
|
#
|
68
87
|
# ==== Block Parameters
|
69
|
-
# * <tt>name</tt> - The callback to be added
|
70
|
-
# * <tt>options</tt> - A hash of options to be used when adding the callback
|
88
|
+
# * <tt>name</tt> - The callback to be added.
|
89
|
+
# * <tt>options</tt> - A hash of options to be used when adding the callback.
|
71
90
|
def _insert_callbacks(callbacks, block = nil)
|
72
91
|
options = callbacks.extract_options!
|
73
92
|
_normalize_callback_options(options)
|
@@ -169,14 +188,22 @@ module AbstractController
|
|
169
188
|
set_callback(:process_action, callback, name, options)
|
170
189
|
end
|
171
190
|
end
|
172
|
-
|
191
|
+
|
192
|
+
define_method "#{callback}_filter" do |*names, &blk|
|
193
|
+
ActiveSupport::Deprecation.warn("#{callback}_filter is deprecated and will be removed in Rails 5.1. Use #{callback}_action instead.")
|
194
|
+
send("#{callback}_action", *names, &blk)
|
195
|
+
end
|
173
196
|
|
174
197
|
define_method "prepend_#{callback}_action" do |*names, &blk|
|
175
198
|
_insert_callbacks(names, blk) do |name, options|
|
176
199
|
set_callback(:process_action, callback, name, options.merge(:prepend => true))
|
177
200
|
end
|
178
201
|
end
|
179
|
-
|
202
|
+
|
203
|
+
define_method "prepend_#{callback}_filter" do |*names, &blk|
|
204
|
+
ActiveSupport::Deprecation.warn("prepend_#{callback}_filter is deprecated and will be removed in Rails 5.1. Use prepend_#{callback}_action instead.")
|
205
|
+
send("prepend_#{callback}_action", *names, &blk)
|
206
|
+
end
|
180
207
|
|
181
208
|
# Skip a before, after or around callback. See _insert_callbacks
|
182
209
|
# for details on the allowed parameters.
|
@@ -185,11 +212,19 @@ module AbstractController
|
|
185
212
|
skip_callback(:process_action, callback, name, options)
|
186
213
|
end
|
187
214
|
end
|
188
|
-
|
215
|
+
|
216
|
+
define_method "skip_#{callback}_filter" do |*names, &blk|
|
217
|
+
ActiveSupport::Deprecation.warn("skip_#{callback}_filter is deprecated and will be removed in Rails 5.1. Use skip_#{callback}_action instead.")
|
218
|
+
send("skip_#{callback}_action", *names, &blk)
|
219
|
+
end
|
189
220
|
|
190
221
|
# *_action is the same as append_*_action
|
191
222
|
alias_method :"append_#{callback}_action", :"#{callback}_action"
|
192
|
-
|
223
|
+
|
224
|
+
define_method "append_#{callback}_filter" do |*names, &blk|
|
225
|
+
ActiveSupport::Deprecation.warn("append_#{callback}_filter is deprecated and will be removed in Rails 5.1. Use append_#{callback}_action instead.")
|
226
|
+
send("append_#{callback}_action", *names, &blk)
|
227
|
+
end
|
193
228
|
end
|
194
229
|
end
|
195
230
|
end
|
@@ -4,11 +4,10 @@ module AbstractController
|
|
4
4
|
module Collector
|
5
5
|
def self.generate_method_for_mime(mime)
|
6
6
|
sym = mime.is_a?(Symbol) ? mime : mime.to_sym
|
7
|
-
const = sym.upcase
|
8
7
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
9
|
-
def #{sym}(*args, &block)
|
10
|
-
custom(Mime
|
11
|
-
end
|
8
|
+
def #{sym}(*args, &block)
|
9
|
+
custom(Mime[:#{sym}], *args, &block)
|
10
|
+
end
|
12
11
|
RUBY
|
13
12
|
end
|
14
13
|
|
@@ -23,9 +22,7 @@ module AbstractController
|
|
23
22
|
protected
|
24
23
|
|
25
24
|
def method_missing(symbol, &block)
|
26
|
-
|
27
|
-
|
28
|
-
unless Mime.const_defined?(const_name)
|
25
|
+
unless mime_constant = Mime[symbol]
|
29
26
|
raise NoMethodError, "To respond to a custom format, register it as a MIME type first: " \
|
30
27
|
"http://guides.rubyonrails.org/action_controller_overview.html#restful-downloads. " \
|
31
28
|
"If you meant to respond to a variant like :tablet or :phone, not a custom format, " \
|
@@ -33,8 +30,6 @@ module AbstractController
|
|
33
30
|
"format.html { |html| html.tablet { ... } }"
|
34
31
|
end
|
35
32
|
|
36
|
-
mime_constant = Mime.const_get(const_name)
|
37
|
-
|
38
33
|
if Mime::SET.include?(mime_constant)
|
39
34
|
AbstractController::Collector.generate_method_for_mime(mime_constant)
|
40
35
|
send(symbol, &block)
|
@@ -38,7 +38,8 @@ module AbstractController
|
|
38
38
|
end
|
39
39
|
|
40
40
|
# Declare a controller method as a helper. For example, the following
|
41
|
-
# makes the +current_user+ controller
|
41
|
+
# makes the +current_user+ and +logged_in?+ controller methods available
|
42
|
+
# to the view:
|
42
43
|
# class ApplicationController < ActionController::Base
|
43
44
|
# helper_method :current_user, :logged_in?
|
44
45
|
#
|
@@ -181,10 +182,10 @@ module AbstractController
|
|
181
182
|
end
|
182
183
|
|
183
184
|
def default_helper_module!
|
184
|
-
module_name = name.sub(/Controller$/, '')
|
185
|
+
module_name = name.sub(/Controller$/, ''.freeze)
|
185
186
|
module_path = module_name.underscore
|
186
187
|
helper module_path
|
187
|
-
rescue
|
188
|
+
rescue LoadError => e
|
188
189
|
raise e unless e.is_missing? "helpers/#{module_path}_helper"
|
189
190
|
rescue NameError => e
|
190
191
|
raise e unless e.missing_name? "#{module_name}Helper"
|
@@ -6,9 +6,9 @@ module AbstractController
|
|
6
6
|
define_method(:inherited) do |klass|
|
7
7
|
super(klass)
|
8
8
|
if namespace = klass.parents.detect { |m| m.respond_to?(:railtie_routes_url_helpers) }
|
9
|
-
klass.
|
9
|
+
klass.include(namespace.railtie_routes_url_helpers(include_path_helpers))
|
10
10
|
else
|
11
|
-
klass.
|
11
|
+
klass.include(routes.url_helpers(include_path_helpers))
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'abstract_controller/error'
|
1
2
|
require 'active_support/concern'
|
2
3
|
require 'active_support/core_ext/class/attribute'
|
3
4
|
require 'action_view'
|
@@ -17,24 +18,28 @@ module AbstractController
|
|
17
18
|
extend ActiveSupport::Concern
|
18
19
|
include ActionView::ViewPaths
|
19
20
|
|
20
|
-
#
|
21
|
-
# sticks the result in self.response_body
|
21
|
+
# Normalizes arguments, options and then delegates render_to_body and
|
22
|
+
# sticks the result in <tt>self.response_body</tt>.
|
22
23
|
# :api: public
|
23
24
|
def render(*args, &block)
|
24
25
|
options = _normalize_render(*args, &block)
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
rendered_body = render_to_body(options)
|
27
|
+
if options[:html]
|
28
|
+
_set_html_content_type
|
29
|
+
else
|
30
|
+
_set_rendered_content_type rendered_format
|
31
|
+
end
|
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
45
|
# :api: plugin
|
@@ -51,14 +56,12 @@ module AbstractController
|
|
51
56
|
# Returns Content-Type of rendered content
|
52
57
|
# :api: public
|
53
58
|
def rendered_format
|
54
|
-
Mime
|
59
|
+
Mime[:text]
|
55
60
|
end
|
56
61
|
|
57
|
-
DEFAULT_PROTECTED_INSTANCE_VARIABLES = Set.new %
|
58
|
-
@_action_name @_response_body @_formats @_prefixes
|
59
|
-
|
60
|
-
@_routes @_db_runtime
|
61
|
-
).map(&:to_sym)
|
62
|
+
DEFAULT_PROTECTED_INSTANCE_VARIABLES = Set.new %i(
|
63
|
+
@_action_name @_response_body @_formats @_prefixes
|
64
|
+
)
|
62
65
|
|
63
66
|
# This method should return a hash with assigns.
|
64
67
|
# You can overwrite this configuration per controller.
|
@@ -73,8 +76,9 @@ module AbstractController
|
|
73
76
|
}
|
74
77
|
end
|
75
78
|
|
76
|
-
# Normalize args by converting render "foo" to
|
77
|
-
# render "foo
|
79
|
+
# Normalize args by converting <tt>render "foo"</tt> to
|
80
|
+
# <tt>render :action => "foo"</tt> and <tt>render "foo/bar"</tt> to
|
81
|
+
# <tt>render :file => "foo/bar"</tt>.
|
78
82
|
# :api: plugin
|
79
83
|
def _normalize_args(action=nil, options={})
|
80
84
|
if action.respond_to?(:permitted?)
|
@@ -104,7 +108,13 @@ module AbstractController
|
|
104
108
|
|
105
109
|
# Process the rendered format.
|
106
110
|
# :api: private
|
107
|
-
def _process_format(format
|
111
|
+
def _process_format(format)
|
112
|
+
end
|
113
|
+
|
114
|
+
def _set_html_content_type # :nodoc:
|
115
|
+
end
|
116
|
+
|
117
|
+
def _set_rendered_content_type(format) # :nodoc:
|
108
118
|
end
|
109
119
|
|
110
120
|
# Normalize args and options.
|
@@ -112,7 +122,7 @@ module AbstractController
|
|
112
122
|
def _normalize_render(*args, &block)
|
113
123
|
options = _normalize_args(*args, &block)
|
114
124
|
#TODO: remove defined? when we restore AP <=> AV dependency
|
115
|
-
if defined?(request) && request && request.variant.present?
|
125
|
+
if defined?(request) && !request.nil? && request.variant.present?
|
116
126
|
options[:variant] = request.variant
|
117
127
|
end
|
118
128
|
_normalize_options(options)
|
@@ -8,14 +8,15 @@ module AbstractController
|
|
8
8
|
# <tt>I18n.translate("people.index.foo")</tt>. This makes it less repetitive
|
9
9
|
# to translate many keys within the same controller / action and gives you a
|
10
10
|
# simple framework for scoping them consistently.
|
11
|
-
def translate(
|
12
|
-
key
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
def translate(key, options = {})
|
12
|
+
if key.to_s.first == '.'
|
13
|
+
path = controller_path.tr('/', '.')
|
14
|
+
defaults = [:"#{path}#{key}"]
|
15
|
+
defaults << options[:default] if options[:default]
|
16
|
+
options[:default] = defaults.flatten
|
17
|
+
key = "#{path}.#{action_name}#{key}"
|
16
18
|
end
|
17
|
-
|
18
|
-
I18n.translate(*args)
|
19
|
+
I18n.translate(key, options)
|
19
20
|
end
|
20
21
|
alias :t :translate
|
21
22
|
|
data/lib/abstract_controller.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
require 'action_pack'
|
2
2
|
require 'active_support/rails'
|
3
|
-
require 'active_support/core_ext/module/attr_internal'
|
4
|
-
require 'active_support/core_ext/module/anonymous'
|
5
3
|
require 'active_support/i18n'
|
6
4
|
|
7
5
|
module AbstractController
|
8
6
|
extend ActiveSupport::Autoload
|
9
7
|
|
10
8
|
autoload :Base
|
9
|
+
autoload :Caching
|
11
10
|
autoload :Callbacks
|
12
11
|
autoload :Collector
|
13
12
|
autoload :DoubleRenderError, "abstract_controller/rendering"
|
@@ -17,4 +16,9 @@ module AbstractController
|
|
17
16
|
autoload :Translation
|
18
17
|
autoload :AssetPaths
|
19
18
|
autoload :UrlFor
|
19
|
+
|
20
|
+
def self.eager_load!
|
21
|
+
super
|
22
|
+
AbstractController::Caching.eager_load!
|
23
|
+
end
|
20
24
|
end
|