actionpack 4.2.11.3 → 5.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +379 -462
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -3
- data/lib/abstract_controller.rb +0 -2
- data/lib/abstract_controller/base.rb +17 -32
- data/lib/abstract_controller/callbacks.rb +52 -19
- data/lib/abstract_controller/collector.rb +4 -9
- data/lib/abstract_controller/helpers.rb +2 -2
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -2
- data/lib/abstract_controller/rendering.rb +27 -22
- data/lib/abstract_controller/translation.rb +8 -7
- data/lib/action_controller.rb +4 -3
- data/lib/action_controller/api.rb +146 -0
- data/lib/action_controller/base.rb +6 -10
- data/lib/action_controller/caching.rb +1 -3
- data/lib/action_controller/caching/fragments.rb +48 -3
- data/lib/action_controller/form_builder.rb +48 -0
- data/lib/action_controller/log_subscriber.rb +1 -10
- data/lib/action_controller/metal.rb +89 -62
- data/lib/action_controller/metal/basic_implicit_render.rb +11 -0
- data/lib/action_controller/metal/conditional_get.rb +65 -24
- data/lib/action_controller/metal/cookies.rb +0 -2
- data/lib/action_controller/metal/data_streaming.rb +2 -22
- data/lib/action_controller/metal/etag_with_template_digest.rb +1 -1
- data/lib/action_controller/metal/exceptions.rb +11 -6
- data/lib/action_controller/metal/force_ssl.rb +6 -6
- data/lib/action_controller/metal/head.rb +14 -7
- data/lib/action_controller/metal/helpers.rb +9 -5
- data/lib/action_controller/metal/http_authentication.rb +37 -38
- data/lib/action_controller/metal/implicit_render.rb +23 -6
- data/lib/action_controller/metal/instrumentation.rb +0 -1
- data/lib/action_controller/metal/live.rb +17 -55
- data/lib/action_controller/metal/mime_responds.rb +17 -37
- data/lib/action_controller/metal/params_wrapper.rb +8 -8
- data/lib/action_controller/metal/redirecting.rb +32 -9
- data/lib/action_controller/metal/renderers.rb +10 -8
- data/lib/action_controller/metal/rendering.rb +38 -6
- data/lib/action_controller/metal/request_forgery_protection.rb +67 -35
- data/lib/action_controller/metal/rescue.rb +2 -4
- data/lib/action_controller/metal/streaming.rb +4 -4
- data/lib/action_controller/metal/strong_parameters.rb +231 -78
- data/lib/action_controller/metal/testing.rb +1 -12
- data/lib/action_controller/metal/url_for.rb +12 -5
- data/lib/action_controller/renderer.rb +111 -0
- data/lib/action_controller/template_assertions.rb +9 -0
- data/lib/action_controller/test_case.rb +267 -363
- data/lib/action_dispatch.rb +2 -1
- data/lib/action_dispatch/http/cache.rb +23 -26
- data/lib/action_dispatch/http/filter_parameters.rb +6 -8
- data/lib/action_dispatch/http/filter_redirect.rb +7 -8
- data/lib/action_dispatch/http/headers.rb +28 -11
- data/lib/action_dispatch/http/mime_negotiation.rb +40 -26
- data/lib/action_dispatch/http/mime_type.rb +92 -61
- data/lib/action_dispatch/http/mime_types.rb +1 -4
- data/lib/action_dispatch/http/parameter_filter.rb +18 -8
- data/lib/action_dispatch/http/parameters.rb +45 -41
- data/lib/action_dispatch/http/request.rb +146 -82
- data/lib/action_dispatch/http/response.rb +180 -99
- data/lib/action_dispatch/http/url.rb +117 -8
- data/lib/action_dispatch/journey/formatter.rb +34 -28
- 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_extras.rb +4 -0
- data/lib/action_dispatch/journey/path/pattern.rb +37 -41
- data/lib/action_dispatch/journey/route.rb +71 -17
- data/lib/action_dispatch/journey/router.rb +5 -6
- data/lib/action_dispatch/journey/router/utils.rb +5 -5
- data/lib/action_dispatch/journey/routes.rb +14 -15
- data/lib/action_dispatch/journey/visitors.rb +86 -43
- data/lib/action_dispatch/middleware/cookies.rb +184 -135
- data/lib/action_dispatch/middleware/debug_exceptions.rb +115 -45
- data/lib/action_dispatch/middleware/exception_wrapper.rb +21 -20
- data/lib/action_dispatch/middleware/flash.rb +61 -45
- data/lib/action_dispatch/middleware/load_interlock.rb +21 -0
- data/lib/action_dispatch/middleware/params_parser.rb +30 -46
- data/lib/action_dispatch/middleware/public_exceptions.rb +2 -2
- data/lib/action_dispatch/middleware/reloader.rb +2 -4
- 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 +29 -23
- 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 +93 -36
- data/lib/action_dispatch/middleware/stack.rb +43 -48
- data/lib/action_dispatch/middleware/static.rb +52 -40
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +2 -14
- data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +0 -0
- 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 +0 -2
- data/lib/action_dispatch/request/session.rb +66 -34
- data/lib/action_dispatch/request/utils.rb +51 -19
- data/lib/action_dispatch/routing.rb +3 -8
- data/lib/action_dispatch/routing/inspector.rb +6 -30
- data/lib/action_dispatch/routing/mapper.rb +447 -322
- data/lib/action_dispatch/routing/polymorphic_routes.rb +8 -14
- data/lib/action_dispatch/routing/redirection.rb +3 -3
- data/lib/action_dispatch/routing/route_set.rb +124 -227
- data/lib/action_dispatch/routing/url_for.rb +27 -10
- data/lib/action_dispatch/testing/assertions.rb +1 -1
- data/lib/action_dispatch/testing/assertions/response.rb +27 -9
- data/lib/action_dispatch/testing/assertions/routing.rb +9 -9
- data/lib/action_dispatch/testing/integration.rb +237 -76
- data/lib/action_dispatch/testing/test_process.rb +5 -5
- data/lib/action_dispatch/testing/test_request.rb +12 -21
- data/lib/action_dispatch/testing/test_response.rb +1 -4
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/gem_version.rb +4 -4
- metadata +26 -25
- 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/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_controller.rb
CHANGED
@@ -7,13 +7,15 @@ require 'action_controller/metal/strong_parameters'
|
|
7
7
|
module ActionController
|
8
8
|
extend ActiveSupport::Autoload
|
9
9
|
|
10
|
+
autoload :API
|
10
11
|
autoload :Base
|
11
12
|
autoload :Caching
|
12
13
|
autoload :Metal
|
13
14
|
autoload :Middleware
|
15
|
+
autoload :Renderer
|
16
|
+
autoload :FormBuilder
|
14
17
|
|
15
18
|
autoload_under "metal" do
|
16
|
-
autoload :Compatibility
|
17
19
|
autoload :ConditionalGet
|
18
20
|
autoload :Cookies
|
19
21
|
autoload :DataStreaming
|
@@ -22,13 +24,12 @@ module ActionController
|
|
22
24
|
autoload :ForceSSL
|
23
25
|
autoload :Head
|
24
26
|
autoload :Helpers
|
25
|
-
autoload :HideActions
|
26
27
|
autoload :HttpAuthentication
|
28
|
+
autoload :BasicImplicitRender
|
27
29
|
autoload :ImplicitRender
|
28
30
|
autoload :Instrumentation
|
29
31
|
autoload :MimeResponds
|
30
32
|
autoload :ParamsWrapper
|
31
|
-
autoload :RackDelegation
|
32
33
|
autoload :Redirecting
|
33
34
|
autoload :Renderers
|
34
35
|
autoload :Rendering
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'action_view'
|
2
|
+
require 'action_controller'
|
3
|
+
require 'action_controller/log_subscriber'
|
4
|
+
|
5
|
+
module ActionController
|
6
|
+
# API Controller is a lightweight version of <tt>ActionController::Base</tt>,
|
7
|
+
# created for applications that don't require all functionalities that a complete
|
8
|
+
# \Rails controller provides, allowing you to create controllers with just the
|
9
|
+
# features that you need for API only applications.
|
10
|
+
#
|
11
|
+
# An API Controller is different from a normal controller in the sense that
|
12
|
+
# by default it doesn't include a number of features that are usually required
|
13
|
+
# by browser access only: layouts and templates rendering, cookies, sessions,
|
14
|
+
# flash, assets, and so on. This makes the entire controller stack thinner,
|
15
|
+
# suitable for API applications. It doesn't mean you won't have such
|
16
|
+
# features if you need them: they're all available for you to include in
|
17
|
+
# your application, they're just not part of the default API Controller stack.
|
18
|
+
#
|
19
|
+
# By default, only the ApplicationController in a \Rails application inherits
|
20
|
+
# from <tt>ActionController::API</tt>. All other controllers in turn inherit
|
21
|
+
# from ApplicationController.
|
22
|
+
#
|
23
|
+
# A sample controller could look like this:
|
24
|
+
#
|
25
|
+
# class PostsController < ApplicationController
|
26
|
+
# def index
|
27
|
+
# @posts = Post.all
|
28
|
+
# render json: @posts
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# Request, response and parameters objects all work the exact same way as
|
33
|
+
# <tt>ActionController::Base</tt>.
|
34
|
+
#
|
35
|
+
# == Renders
|
36
|
+
#
|
37
|
+
# The default API Controller stack includes all renderers, which means you
|
38
|
+
# can use <tt>render :json</tt> and brothers freely in your controllers. Keep
|
39
|
+
# in mind that templates are not going to be rendered, so you need to ensure
|
40
|
+
# your controller is calling either <tt>render</tt> or <tt>redirect</tt> in
|
41
|
+
# all actions, otherwise it will return 204 No Content response.
|
42
|
+
#
|
43
|
+
# def show
|
44
|
+
# @post = Post.find(params[:id])
|
45
|
+
# render json: @post
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# == Redirects
|
49
|
+
#
|
50
|
+
# Redirects are used to move from one action to another. You can use the
|
51
|
+
# <tt>redirect</tt> method in your controllers in the same way as
|
52
|
+
# <tt>ActionController::Base</tt>. For example:
|
53
|
+
#
|
54
|
+
# def create
|
55
|
+
# redirect_to root_url and return if not_authorized?
|
56
|
+
# # do stuff here
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
# == Adding new behavior
|
60
|
+
#
|
61
|
+
# In some scenarios you may want to add back some functionality provided by
|
62
|
+
# <tt>ActionController::Base</tt> that is not present by default in
|
63
|
+
# <tt>ActionController::API</tt>, for instance <tt>MimeResponds</tt>. This
|
64
|
+
# module gives you the <tt>respond_to</tt> method. Adding it is quite simple,
|
65
|
+
# you just need to include the module in a specific controller or in
|
66
|
+
# +ApplicationController+ in case you want it available in your entire
|
67
|
+
# application:
|
68
|
+
#
|
69
|
+
# class ApplicationController < ActionController::API
|
70
|
+
# include ActionController::MimeResponds
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# class PostsController < ApplicationController
|
74
|
+
# def index
|
75
|
+
# @posts = Post.all
|
76
|
+
#
|
77
|
+
# respond_to do |format|
|
78
|
+
# format.json { render json: @posts }
|
79
|
+
# format.xml { render xml: @posts }
|
80
|
+
# end
|
81
|
+
# end
|
82
|
+
# end
|
83
|
+
#
|
84
|
+
# Quite straightforward. Make sure to check <tt>ActionController::Base</tt>
|
85
|
+
# available modules if you want to include any other functionality that is
|
86
|
+
# not provided by <tt>ActionController::API</tt> out of the box.
|
87
|
+
class API < Metal
|
88
|
+
abstract!
|
89
|
+
|
90
|
+
# Shortcut helper that returns all the ActionController::API modules except
|
91
|
+
# the ones passed as arguments:
|
92
|
+
#
|
93
|
+
# class MyAPIBaseController < ActionController::Metal
|
94
|
+
# ActionController::API.without_modules(:ForceSSL, :UrlFor).each do |left|
|
95
|
+
# include left
|
96
|
+
# end
|
97
|
+
# end
|
98
|
+
#
|
99
|
+
# This gives better control over what you want to exclude and makes it easier
|
100
|
+
# to create an API controller class, instead of listing the modules required
|
101
|
+
# manually.
|
102
|
+
def self.without_modules(*modules)
|
103
|
+
modules = modules.map do |m|
|
104
|
+
m.is_a?(Symbol) ? ActionController.const_get(m) : m
|
105
|
+
end
|
106
|
+
|
107
|
+
MODULES - modules
|
108
|
+
end
|
109
|
+
|
110
|
+
MODULES = [
|
111
|
+
AbstractController::Rendering,
|
112
|
+
|
113
|
+
UrlFor,
|
114
|
+
Redirecting,
|
115
|
+
Rendering,
|
116
|
+
Renderers::All,
|
117
|
+
ConditionalGet,
|
118
|
+
BasicImplicitRender,
|
119
|
+
StrongParameters,
|
120
|
+
|
121
|
+
ForceSSL,
|
122
|
+
DataStreaming,
|
123
|
+
|
124
|
+
# Before callbacks should also be executed as early as possible, so
|
125
|
+
# also include them at the bottom.
|
126
|
+
AbstractController::Callbacks,
|
127
|
+
|
128
|
+
# Append rescue at the bottom to wrap as much as possible.
|
129
|
+
Rescue,
|
130
|
+
|
131
|
+
# Add instrumentations hooks at the bottom, to ensure they instrument
|
132
|
+
# all the methods properly.
|
133
|
+
Instrumentation,
|
134
|
+
|
135
|
+
# Params wrapper should come before instrumentation so they are
|
136
|
+
# properly showed in logs
|
137
|
+
ParamsWrapper
|
138
|
+
]
|
139
|
+
|
140
|
+
MODULES.each do |mod|
|
141
|
+
include mod
|
142
|
+
end
|
143
|
+
|
144
|
+
ActiveSupport.run_load_hooks(:action_controller, self)
|
145
|
+
end
|
146
|
+
end
|
@@ -50,9 +50,9 @@ module ActionController
|
|
50
50
|
#
|
51
51
|
# == Parameters
|
52
52
|
#
|
53
|
-
# All request parameters, whether they come from a
|
54
|
-
# which returns a hash. For example, an action that was performed through
|
55
|
-
# <tt>{ "category" => "All", "limit" => "5" }</tt> in params.
|
53
|
+
# All request parameters, whether they come from a query string in the URL or form data submitted through a POST request are
|
54
|
+
# available through the params method which returns a hash. For example, an action that was performed through
|
55
|
+
# <tt>/posts?category=All&limit=5</tt> will include <tt>{ "category" => "All", "limit" => "5" }</tt> in params.
|
56
56
|
#
|
57
57
|
# It's also possible to construct multi-dimensional parameter hashes by specifying keys using brackets, such as:
|
58
58
|
#
|
@@ -206,7 +206,6 @@ module ActionController
|
|
206
206
|
AbstractController::AssetPaths,
|
207
207
|
|
208
208
|
Helpers,
|
209
|
-
HideActions,
|
210
209
|
UrlFor,
|
211
210
|
Redirecting,
|
212
211
|
ActionView::Layouts,
|
@@ -214,7 +213,6 @@ module ActionController
|
|
214
213
|
Renderers::All,
|
215
214
|
ConditionalGet,
|
216
215
|
EtagWithTemplateDigest,
|
217
|
-
RackDelegation,
|
218
216
|
Caching,
|
219
217
|
MimeResponds,
|
220
218
|
ImplicitRender,
|
@@ -222,6 +220,7 @@ module ActionController
|
|
222
220
|
|
223
221
|
Cookies,
|
224
222
|
Flash,
|
223
|
+
FormBuilder,
|
225
224
|
RequestForgeryProtection,
|
226
225
|
ForceSSL,
|
227
226
|
Streaming,
|
@@ -249,20 +248,17 @@ module ActionController
|
|
249
248
|
MODULES.each do |mod|
|
250
249
|
include mod
|
251
250
|
end
|
251
|
+
setup_renderer!
|
252
252
|
|
253
253
|
# Define some internal variables that should not be propagated to the view.
|
254
254
|
PROTECTED_IVARS = AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + [
|
255
|
-
:@
|
255
|
+
:@_params, :@_response, :@_request,
|
256
256
|
:@_view_runtime, :@_stream, :@_url_options, :@_action_has_layout ]
|
257
257
|
|
258
258
|
def _protected_ivars # :nodoc:
|
259
259
|
PROTECTED_IVARS
|
260
260
|
end
|
261
261
|
|
262
|
-
def self.protected_instance_variables
|
263
|
-
PROTECTED_IVARS
|
264
|
-
end
|
265
|
-
|
266
262
|
ActiveSupport.run_load_hooks(:action_controller, self)
|
267
263
|
end
|
268
264
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
require 'uri'
|
3
|
-
require 'set'
|
4
3
|
|
5
4
|
module ActionController
|
6
5
|
# \Caching is a cheap way of speeding up slow applications by keeping the result of
|
@@ -8,7 +7,7 @@ module ActionController
|
|
8
7
|
#
|
9
8
|
# You can read more about each approach by clicking the modules below.
|
10
9
|
#
|
11
|
-
# Note: To turn off all caching, set
|
10
|
+
# Note: To turn off all caching provided by Action Controller, set
|
12
11
|
# config.action_controller.perform_caching = false
|
13
12
|
#
|
14
13
|
# == \Caching stores
|
@@ -46,7 +45,6 @@ module ActionController
|
|
46
45
|
end
|
47
46
|
end
|
48
47
|
|
49
|
-
include RackDelegation
|
50
48
|
include AbstractController::Callbacks
|
51
49
|
|
52
50
|
include ConfigMethods
|
@@ -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
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module ActionController
|
2
|
+
# Override the default form builder for all views rendered by this
|
3
|
+
# controller and any of its descendants. Accepts a subclass of
|
4
|
+
# +ActionView::Helpers::FormBuilder+.
|
5
|
+
#
|
6
|
+
# For example, given a form builder:
|
7
|
+
#
|
8
|
+
# class AdminFormBuilder < ActionView::Helpers::FormBuilder
|
9
|
+
# def special_field(name)
|
10
|
+
# end
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# The controller specifies a form builder as its default:
|
14
|
+
#
|
15
|
+
# class AdminAreaController < ApplicationController
|
16
|
+
# default_form_builder AdminFormBuilder
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# Then in the view any form using +form_for+ will be an instance of the
|
20
|
+
# specified form builder:
|
21
|
+
#
|
22
|
+
# <%= form_for(@instance) do |builder| %>
|
23
|
+
# <%= builder.special_field(:name) %>
|
24
|
+
# <% end %>
|
25
|
+
module FormBuilder
|
26
|
+
extend ActiveSupport::Concern
|
27
|
+
|
28
|
+
included do
|
29
|
+
class_attribute :_default_form_builder, instance_accessor: false
|
30
|
+
end
|
31
|
+
|
32
|
+
module ClassMethods
|
33
|
+
# Set the form builder to be used as the default for all forms
|
34
|
+
# in the views rendered by this controller and its subclasses.
|
35
|
+
#
|
36
|
+
# ==== Parameters
|
37
|
+
# * <tt>builder</tt> - Default form builder, an instance of +ActionView::Helpers::FormBuilder+
|
38
|
+
def default_form_builder(builder)
|
39
|
+
self._default_form_builder = builder
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Default form builder for the controller
|
44
|
+
def default_form_builder
|
45
|
+
self.class._default_form_builder
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -25,7 +25,7 @@ module ActionController
|
|
25
25
|
status = ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name)
|
26
26
|
end
|
27
27
|
message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{event.duration.round}ms"
|
28
|
-
message << " (#{additions.join(" | ")})" unless additions.blank?
|
28
|
+
message << " (#{additions.join(" | ".freeze)})" unless additions.blank?
|
29
29
|
message
|
30
30
|
end
|
31
31
|
end
|
@@ -53,15 +53,6 @@ module ActionController
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
def deep_munge(event)
|
57
|
-
debug do
|
58
|
-
"Value for params[:#{event.payload[:keys].join('][:')}] was set "\
|
59
|
-
"to nil, because it was one of [], [null] or [null, null, ...]. "\
|
60
|
-
"Go to http://guides.rubyonrails.org/security.html#unsafe-query-generation "\
|
61
|
-
"for more information."\
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
56
|
%w(write_fragment read_fragment exist_fragment?
|
66
57
|
expire_fragment expire_page write_page).each do |method|
|
67
58
|
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'active_support/core_ext/array/extract_options'
|
2
2
|
require 'action_dispatch/middleware/stack'
|
3
|
+
require 'action_dispatch/http/request'
|
4
|
+
require 'action_dispatch/http/response'
|
3
5
|
|
4
6
|
module ActionController
|
5
7
|
# Extend ActionDispatch middleware stack to make it aware of options
|
@@ -11,22 +13,14 @@ module ActionController
|
|
11
13
|
#
|
12
14
|
class MiddlewareStack < ActionDispatch::MiddlewareStack #:nodoc:
|
13
15
|
class Middleware < ActionDispatch::MiddlewareStack::Middleware #:nodoc:
|
14
|
-
def initialize(klass,
|
15
|
-
|
16
|
-
@
|
17
|
-
|
18
|
-
args << options unless options.empty?
|
19
|
-
super
|
16
|
+
def initialize(klass, args, actions, strategy, block)
|
17
|
+
@actions = actions
|
18
|
+
@strategy = strategy
|
19
|
+
super(klass, args, block)
|
20
20
|
end
|
21
21
|
|
22
22
|
def valid?(action)
|
23
|
-
|
24
|
-
@only.include?(action)
|
25
|
-
elsif @except.present?
|
26
|
-
!@except.include?(action)
|
27
|
-
else
|
28
|
-
true
|
29
|
-
end
|
23
|
+
@strategy.call @actions, action
|
30
24
|
end
|
31
25
|
end
|
32
26
|
|
@@ -37,6 +31,32 @@ module ActionController
|
|
37
31
|
middleware.valid?(action) ? middleware.build(a) : a
|
38
32
|
end
|
39
33
|
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
INCLUDE = ->(list, action) { list.include? action }
|
38
|
+
EXCLUDE = ->(list, action) { !list.include? action }
|
39
|
+
NULL = ->(list, action) { true }
|
40
|
+
|
41
|
+
def build_middleware(klass, args, block)
|
42
|
+
options = args.extract_options!
|
43
|
+
only = Array(options.delete(:only)).map(&:to_s)
|
44
|
+
except = Array(options.delete(:except)).map(&:to_s)
|
45
|
+
args << options unless options.empty?
|
46
|
+
|
47
|
+
strategy = NULL
|
48
|
+
list = nil
|
49
|
+
|
50
|
+
if only.any?
|
51
|
+
strategy = INCLUDE
|
52
|
+
list = only
|
53
|
+
elsif except.any?
|
54
|
+
strategy = EXCLUDE
|
55
|
+
list = except
|
56
|
+
end
|
57
|
+
|
58
|
+
Middleware.new(get_class(klass), args, list, strategy, block)
|
59
|
+
end
|
40
60
|
end
|
41
61
|
|
42
62
|
# <tt>ActionController::Metal</tt> is the simplest possible controller, providing a
|
@@ -98,11 +118,10 @@ module ActionController
|
|
98
118
|
class Metal < AbstractController::Base
|
99
119
|
abstract!
|
100
120
|
|
101
|
-
attr_internal_writer :env
|
102
|
-
|
103
121
|
def env
|
104
|
-
@
|
122
|
+
@_request.env
|
105
123
|
end
|
124
|
+
deprecate :env
|
106
125
|
|
107
126
|
# Returns the last part of the controller's name, underscored, without the ending
|
108
127
|
# <tt>Controller</tt>. For instance, PostsController returns <tt>posts</tt>.
|
@@ -114,23 +133,23 @@ module ActionController
|
|
114
133
|
@controller_name ||= name.demodulize.sub(/Controller$/, '').underscore
|
115
134
|
end
|
116
135
|
|
136
|
+
def self.make_response!(request)
|
137
|
+
ActionDispatch::Response.create.tap do |res|
|
138
|
+
res.request = request
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
117
142
|
# Delegates to the class' <tt>controller_name</tt>
|
118
143
|
def controller_name
|
119
144
|
self.class.controller_name
|
120
145
|
end
|
121
146
|
|
122
|
-
|
123
|
-
# Request and Response object. The default ActionController::Base
|
124
|
-
# implementation includes RackDelegation, which makes a request
|
125
|
-
# and response object available. You might wish to control the
|
126
|
-
# environment and response manually for performance reasons.
|
127
|
-
|
128
|
-
attr_internal :headers, :response, :request
|
147
|
+
attr_internal :response, :request
|
129
148
|
delegate :session, :to => "@_request"
|
149
|
+
delegate :headers, :status=, :location=, :content_type=,
|
150
|
+
:status, :location, :content_type, :to => "@_response"
|
130
151
|
|
131
152
|
def initialize
|
132
|
-
@_headers = {"Content-Type" => "text/html"}
|
133
|
-
@_status = 200
|
134
153
|
@_request = nil
|
135
154
|
@_response = nil
|
136
155
|
@_routes = nil
|
@@ -145,60 +164,51 @@ module ActionController
|
|
145
164
|
@_params = val
|
146
165
|
end
|
147
166
|
|
148
|
-
|
149
|
-
# provided to reduce the dependency on the RackDelegation module
|
150
|
-
# in Renderer and Redirector.
|
151
|
-
|
152
|
-
def content_type=(type)
|
153
|
-
headers["Content-Type"] = type.to_s
|
154
|
-
end
|
155
|
-
|
156
|
-
def content_type
|
157
|
-
headers["Content-Type"]
|
158
|
-
end
|
159
|
-
|
160
|
-
def location
|
161
|
-
headers["Location"]
|
162
|
-
end
|
163
|
-
|
164
|
-
def location=(url)
|
165
|
-
headers["Location"] = url
|
166
|
-
end
|
167
|
+
alias :response_code :status # :nodoc:
|
167
168
|
|
168
169
|
# Basic url_for that can be overridden for more robust functionality
|
169
170
|
def url_for(string)
|
170
171
|
string
|
171
172
|
end
|
172
173
|
|
173
|
-
def status
|
174
|
-
@_status
|
175
|
-
end
|
176
|
-
alias :response_code :status # :nodoc:
|
177
|
-
|
178
|
-
def status=(status)
|
179
|
-
@_status = Rack::Utils.status_code(status)
|
180
|
-
end
|
181
|
-
|
182
174
|
def response_body=(body)
|
183
175
|
body = [body] unless body.nil? || body.respond_to?(:each)
|
176
|
+
response.reset_body!
|
177
|
+
body.each { |part|
|
178
|
+
next if part.empty?
|
179
|
+
response.write part
|
180
|
+
}
|
184
181
|
super
|
185
182
|
end
|
186
183
|
|
187
184
|
# Tests if render or redirect has already happened.
|
188
185
|
def performed?
|
189
|
-
response_body ||
|
186
|
+
response_body || response.committed?
|
190
187
|
end
|
191
188
|
|
192
|
-
def dispatch(name, request) #:nodoc:
|
193
|
-
|
194
|
-
|
195
|
-
@_env['action_controller.instance'] = self
|
189
|
+
def dispatch(name, request, response) #:nodoc:
|
190
|
+
set_request!(request)
|
191
|
+
set_response!(response)
|
196
192
|
process(name)
|
193
|
+
request.commit_flash
|
197
194
|
to_a
|
198
195
|
end
|
199
196
|
|
197
|
+
def set_response!(response) # :nodoc:
|
198
|
+
@_response = response
|
199
|
+
end
|
200
|
+
|
201
|
+
def set_request!(request) #:nodoc:
|
202
|
+
@_request = request
|
203
|
+
@_request.controller_instance = self
|
204
|
+
end
|
205
|
+
|
200
206
|
def to_a #:nodoc:
|
201
|
-
response
|
207
|
+
response.to_a
|
208
|
+
end
|
209
|
+
|
210
|
+
def reset_session
|
211
|
+
@_request.reset_session
|
202
212
|
end
|
203
213
|
|
204
214
|
class_attribute :middleware_stack
|
@@ -226,15 +236,32 @@ module ActionController
|
|
226
236
|
req = ActionDispatch::Request.new env
|
227
237
|
action(req.path_parameters[:action]).call(env)
|
228
238
|
end
|
239
|
+
class << self; deprecate :call; end
|
229
240
|
|
230
241
|
# Returns a Rack endpoint for the given action name.
|
231
|
-
def self.action(name
|
242
|
+
def self.action(name)
|
232
243
|
if middleware_stack.any?
|
233
244
|
middleware_stack.build(name) do |env|
|
234
|
-
|
245
|
+
req = ActionDispatch::Request.new(env)
|
246
|
+
res = make_response! req
|
247
|
+
new.dispatch(name, req, res)
|
235
248
|
end
|
236
249
|
else
|
237
|
-
lambda { |env|
|
250
|
+
lambda { |env|
|
251
|
+
req = ActionDispatch::Request.new(env)
|
252
|
+
res = make_response! req
|
253
|
+
new.dispatch(name, req, res)
|
254
|
+
}
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
# Direct dispatch to the controller. Instantiates the controller, then
|
259
|
+
# executes the action named +name+.
|
260
|
+
def self.dispatch(name, req, res)
|
261
|
+
if middleware_stack.any?
|
262
|
+
middleware_stack.build(name) { |env| new.dispatch(name, req, res) }.call req.env
|
263
|
+
else
|
264
|
+
new.dispatch(name, req, res)
|
238
265
|
end
|
239
266
|
end
|
240
267
|
end
|