actionpack 4.0.1 → 4.2.11.1
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 +402 -1173
- data/MIT-LICENSE +1 -1
- data/README.rdoc +7 -7
- data/lib/abstract_controller/base.rb +39 -7
- data/lib/abstract_controller/callbacks.rb +32 -53
- data/lib/abstract_controller/collector.rb +11 -1
- data/lib/abstract_controller/helpers.rb +26 -16
- data/lib/abstract_controller/railties/routes_helpers.rb +3 -3
- data/lib/abstract_controller/rendering.rb +57 -127
- data/lib/abstract_controller/url_for.rb +1 -1
- data/lib/abstract_controller.rb +1 -2
- data/lib/action_controller/base.rb +19 -10
- data/lib/action_controller/caching/fragments.rb +7 -1
- data/lib/action_controller/caching.rb +2 -12
- data/lib/action_controller/log_subscriber.rb +29 -20
- data/lib/action_controller/metal/conditional_get.rb +37 -12
- data/lib/action_controller/metal/data_streaming.rb +1 -1
- data/lib/action_controller/metal/etag_with_template_digest.rb +50 -0
- data/lib/action_controller/metal/exceptions.rb +1 -1
- data/lib/action_controller/metal/flash.rb +17 -0
- data/lib/action_controller/metal/force_ssl.rb +2 -2
- data/lib/action_controller/metal/head.rb +8 -6
- data/lib/action_controller/metal/helpers.rb +6 -2
- data/lib/action_controller/metal/http_authentication.rb +45 -23
- data/lib/action_controller/metal/instrumentation.rb +9 -6
- data/lib/action_controller/metal/live.rb +173 -20
- data/lib/action_controller/metal/mime_responds.rb +127 -232
- data/lib/action_controller/metal/params_wrapper.rb +16 -9
- data/lib/action_controller/metal/rack_delegation.rb +1 -1
- data/lib/action_controller/metal/redirecting.rb +34 -26
- data/lib/action_controller/metal/renderers.rb +39 -12
- data/lib/action_controller/metal/rendering.rb +41 -14
- data/lib/action_controller/metal/request_forgery_protection.rb +147 -19
- data/lib/action_controller/metal/streaming.rb +19 -21
- data/lib/action_controller/metal/strong_parameters.rb +166 -22
- data/lib/action_controller/metal/testing.rb +0 -1
- data/lib/action_controller/metal/url_for.rb +11 -12
- data/lib/action_controller/metal.rb +14 -8
- data/lib/action_controller/model_naming.rb +1 -1
- data/lib/action_controller/railtie.rb +5 -1
- data/lib/action_controller/test_case.rb +160 -94
- data/lib/action_controller.rb +2 -18
- data/lib/action_dispatch/http/cache.rb +5 -4
- data/lib/action_dispatch/http/filter_parameters.rb +2 -2
- data/lib/action_dispatch/http/filter_redirect.rb +5 -4
- data/lib/action_dispatch/http/headers.rb +46 -10
- data/lib/action_dispatch/http/mime_negotiation.rb +31 -4
- data/lib/action_dispatch/http/mime_type.rb +25 -26
- data/lib/action_dispatch/http/mime_types.rb +1 -0
- data/lib/action_dispatch/http/parameter_filter.rb +1 -1
- data/lib/action_dispatch/http/parameters.rb +25 -41
- data/lib/action_dispatch/http/request.rb +49 -32
- data/lib/action_dispatch/http/response.rb +127 -25
- data/lib/action_dispatch/http/upload.rb +9 -21
- data/lib/action_dispatch/http/url.rb +97 -70
- data/lib/action_dispatch/journey/formatter.rb +35 -19
- data/lib/action_dispatch/journey/gtg/builder.rb +3 -3
- data/lib/action_dispatch/journey/gtg/simulator.rb +10 -7
- data/lib/action_dispatch/journey/gtg/transition_table.rb +23 -33
- data/lib/action_dispatch/journey/nfa/dot.rb +2 -2
- data/lib/action_dispatch/journey/nfa/simulator.rb +1 -1
- data/lib/action_dispatch/journey/nfa/transition_table.rb +5 -5
- data/lib/action_dispatch/journey/nodes/node.rb +4 -0
- data/lib/action_dispatch/journey/parser.rb +51 -59
- data/lib/action_dispatch/journey/parser.y +12 -10
- data/lib/action_dispatch/journey/path/pattern.rb +16 -19
- data/lib/action_dispatch/journey/route.rb +8 -19
- data/lib/action_dispatch/journey/router/strexp.rb +9 -6
- data/lib/action_dispatch/journey/router/utils.rb +54 -18
- data/lib/action_dispatch/journey/router.rb +53 -75
- data/lib/action_dispatch/journey/routes.rb +4 -0
- data/lib/action_dispatch/journey/scanner.rb +5 -5
- data/lib/action_dispatch/journey/visitors.rb +81 -60
- data/lib/action_dispatch/journey/visualizer/fsm.css +0 -4
- data/lib/action_dispatch/journey/visualizer/index.html.erb +2 -2
- data/lib/action_dispatch/middleware/callbacks.rb +7 -7
- data/lib/action_dispatch/middleware/cookies.rb +119 -43
- data/lib/action_dispatch/middleware/debug_exceptions.rb +32 -13
- data/lib/action_dispatch/middleware/exception_wrapper.rb +60 -20
- data/lib/action_dispatch/middleware/flash.rb +37 -24
- data/lib/action_dispatch/middleware/params_parser.rb +2 -2
- data/lib/action_dispatch/middleware/public_exceptions.rb +12 -3
- data/lib/action_dispatch/middleware/reloader.rb +11 -2
- data/lib/action_dispatch/middleware/remote_ip.rb +40 -54
- data/lib/action_dispatch/middleware/request_id.rb +1 -1
- data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
- data/lib/action_dispatch/middleware/session/cookie_store.rb +8 -7
- data/lib/action_dispatch/middleware/show_exceptions.rb +6 -2
- data/lib/action_dispatch/middleware/ssl.rb +10 -7
- data/lib/action_dispatch/middleware/static.rb +79 -23
- data/lib/action_dispatch/middleware/templates/rescues/{_request_and_response.erb → _request_and_response.html.erb} +0 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
- data/lib/action_dispatch/middleware/templates/rescues/_source.erb +21 -19
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
- data/lib/action_dispatch/middleware/templates/rescues/{diagnostics.erb → diagnostics.html.erb} +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +6 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/{routing_error.erb → routing_error.html.erb} +3 -1
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
- data/lib/action_dispatch/middleware/templates/rescues/{unknown_action.erb → unknown_action.html.erb} +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +120 -64
- data/lib/action_dispatch/railtie.rb +5 -2
- data/lib/action_dispatch/request/session.rb +12 -0
- data/lib/action_dispatch/request/utils.rb +35 -0
- data/lib/action_dispatch/routing/endpoint.rb +10 -0
- data/lib/action_dispatch/routing/inspector.rb +11 -17
- data/lib/action_dispatch/routing/mapper.rb +519 -312
- data/lib/action_dispatch/routing/polymorphic_routes.rb +204 -79
- data/lib/action_dispatch/routing/redirection.rb +51 -26
- data/lib/action_dispatch/routing/route_set.rb +331 -206
- data/lib/action_dispatch/routing/routes_proxy.rb +5 -4
- data/lib/action_dispatch/routing/url_for.rb +19 -5
- data/lib/action_dispatch/routing.rb +9 -6
- data/lib/action_dispatch/testing/assertions/dom.rb +2 -26
- data/lib/action_dispatch/testing/assertions/response.rb +9 -15
- data/lib/action_dispatch/testing/assertions/routing.rb +22 -22
- data/lib/action_dispatch/testing/assertions/selector.rb +2 -429
- data/lib/action_dispatch/testing/assertions/tag.rb +2 -134
- data/lib/action_dispatch/testing/assertions.rb +11 -7
- data/lib/action_dispatch/testing/integration.rb +31 -29
- data/lib/action_dispatch/testing/test_request.rb +1 -1
- data/lib/action_dispatch/testing/test_response.rb +1 -5
- data/lib/action_dispatch.rb +5 -8
- data/lib/action_pack/gem_version.rb +15 -0
- data/lib/action_pack/version.rb +4 -7
- data/lib/action_pack.rb +1 -1
- metadata +77 -159
- data/lib/abstract_controller/layouts.rb +0 -423
- data/lib/abstract_controller/view_paths.rb +0 -96
- data/lib/action_controller/deprecated/integration_test.rb +0 -5
- data/lib/action_controller/deprecated.rb +0 -7
- data/lib/action_controller/metal/responder.rb +0 -287
- data/lib/action_controller/record_identifier.rb +0 -31
- data/lib/action_controller/vendor/html-scanner.rb +0 -5
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +0 -24
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +0 -7
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +0 -43
- data/lib/action_view/base.rb +0 -201
- data/lib/action_view/buffers.rb +0 -49
- data/lib/action_view/context.rb +0 -36
- data/lib/action_view/dependency_tracker.rb +0 -93
- data/lib/action_view/digestor.rb +0 -113
- data/lib/action_view/flows.rb +0 -76
- data/lib/action_view/helpers/active_model_helper.rb +0 -49
- data/lib/action_view/helpers/asset_tag_helper.rb +0 -320
- data/lib/action_view/helpers/asset_url_helper.rb +0 -355
- data/lib/action_view/helpers/atom_feed_helper.rb +0 -203
- data/lib/action_view/helpers/cache_helper.rb +0 -196
- data/lib/action_view/helpers/capture_helper.rb +0 -216
- data/lib/action_view/helpers/controller_helper.rb +0 -25
- data/lib/action_view/helpers/csrf_helper.rb +0 -30
- data/lib/action_view/helpers/date_helper.rb +0 -1083
- data/lib/action_view/helpers/debug_helper.rb +0 -39
- data/lib/action_view/helpers/form_helper.rb +0 -1880
- data/lib/action_view/helpers/form_options_helper.rb +0 -838
- data/lib/action_view/helpers/form_tag_helper.rb +0 -785
- data/lib/action_view/helpers/javascript_helper.rb +0 -117
- data/lib/action_view/helpers/number_helper.rb +0 -441
- data/lib/action_view/helpers/output_safety_helper.rb +0 -38
- data/lib/action_view/helpers/record_tag_helper.rb +0 -106
- data/lib/action_view/helpers/rendering_helper.rb +0 -90
- data/lib/action_view/helpers/sanitize_helper.rb +0 -256
- data/lib/action_view/helpers/tag_helper.rb +0 -173
- data/lib/action_view/helpers/tags/base.rb +0 -148
- data/lib/action_view/helpers/tags/check_box.rb +0 -64
- data/lib/action_view/helpers/tags/checkable.rb +0 -16
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +0 -44
- data/lib/action_view/helpers/tags/collection_helpers.rb +0 -84
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +0 -36
- data/lib/action_view/helpers/tags/collection_select.rb +0 -28
- data/lib/action_view/helpers/tags/color_field.rb +0 -25
- data/lib/action_view/helpers/tags/date_field.rb +0 -13
- data/lib/action_view/helpers/tags/date_select.rb +0 -72
- data/lib/action_view/helpers/tags/datetime_field.rb +0 -22
- data/lib/action_view/helpers/tags/datetime_local_field.rb +0 -19
- data/lib/action_view/helpers/tags/datetime_select.rb +0 -8
- data/lib/action_view/helpers/tags/email_field.rb +0 -8
- data/lib/action_view/helpers/tags/file_field.rb +0 -8
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +0 -29
- data/lib/action_view/helpers/tags/hidden_field.rb +0 -8
- data/lib/action_view/helpers/tags/label.rb +0 -66
- data/lib/action_view/helpers/tags/month_field.rb +0 -13
- data/lib/action_view/helpers/tags/number_field.rb +0 -18
- data/lib/action_view/helpers/tags/password_field.rb +0 -12
- data/lib/action_view/helpers/tags/radio_button.rb +0 -31
- data/lib/action_view/helpers/tags/range_field.rb +0 -8
- data/lib/action_view/helpers/tags/search_field.rb +0 -24
- data/lib/action_view/helpers/tags/select.rb +0 -40
- data/lib/action_view/helpers/tags/tel_field.rb +0 -8
- data/lib/action_view/helpers/tags/text_area.rb +0 -18
- data/lib/action_view/helpers/tags/text_field.rb +0 -29
- data/lib/action_view/helpers/tags/time_field.rb +0 -13
- data/lib/action_view/helpers/tags/time_select.rb +0 -8
- data/lib/action_view/helpers/tags/time_zone_select.rb +0 -20
- data/lib/action_view/helpers/tags/url_field.rb +0 -8
- data/lib/action_view/helpers/tags/week_field.rb +0 -13
- data/lib/action_view/helpers/tags.rb +0 -39
- data/lib/action_view/helpers/text_helper.rb +0 -443
- data/lib/action_view/helpers/translation_helper.rb +0 -107
- data/lib/action_view/helpers/url_helper.rb +0 -635
- data/lib/action_view/helpers.rb +0 -58
- data/lib/action_view/locale/en.yml +0 -56
- data/lib/action_view/log_subscriber.rb +0 -30
- data/lib/action_view/lookup_context.rb +0 -241
- data/lib/action_view/model_naming.rb +0 -12
- data/lib/action_view/path_set.rb +0 -77
- data/lib/action_view/railtie.rb +0 -43
- data/lib/action_view/record_identifier.rb +0 -84
- data/lib/action_view/renderer/abstract_renderer.rb +0 -47
- data/lib/action_view/renderer/partial_renderer.rb +0 -492
- data/lib/action_view/renderer/renderer.rb +0 -50
- data/lib/action_view/renderer/streaming_template_renderer.rb +0 -103
- data/lib/action_view/renderer/template_renderer.rb +0 -96
- data/lib/action_view/routing_url_for.rb +0 -107
- data/lib/action_view/tasks/dependencies.rake +0 -17
- data/lib/action_view/template/error.rb +0 -138
- data/lib/action_view/template/handlers/builder.rb +0 -26
- data/lib/action_view/template/handlers/erb.rb +0 -146
- data/lib/action_view/template/handlers/raw.rb +0 -11
- data/lib/action_view/template/handlers.rb +0 -53
- data/lib/action_view/template/resolver.rb +0 -326
- data/lib/action_view/template/text.rb +0 -34
- data/lib/action_view/template/types.rb +0 -57
- data/lib/action_view/template.rb +0 -339
- data/lib/action_view/test_case.rb +0 -270
- data/lib/action_view/testing/resolvers.rb +0 -50
- data/lib/action_view/vendor/html-scanner/html/document.rb +0 -68
- data/lib/action_view/vendor/html-scanner/html/node.rb +0 -532
- data/lib/action_view/vendor/html-scanner/html/sanitizer.rb +0 -188
- data/lib/action_view/vendor/html-scanner/html/selector.rb +0 -830
- data/lib/action_view/vendor/html-scanner/html/tokenizer.rb +0 -107
- data/lib/action_view/vendor/html-scanner/html/version.rb +0 -11
- data/lib/action_view/vendor/html-scanner.rb +0 -20
- data/lib/action_view.rb +0 -93
@@ -1,61 +1,28 @@
|
|
1
|
-
require 'active_support/core_ext/array/extract_options'
|
2
1
|
require 'abstract_controller/collector'
|
3
2
|
|
4
3
|
module ActionController #:nodoc:
|
5
4
|
module MimeResponds
|
6
5
|
extend ActiveSupport::Concern
|
7
6
|
|
8
|
-
|
9
|
-
class_attribute :responder, :mimes_for_respond_to
|
10
|
-
self.responder = ActionController::Responder
|
11
|
-
clear_respond_to
|
12
|
-
end
|
13
|
-
|
7
|
+
# :stopdoc:
|
14
8
|
module ClassMethods
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
# for <tt>:html</tt>, <tt>:xml</tt> and <tt>:json</tt>.
|
22
|
-
#
|
23
|
-
# To specify on per-action basis, use <tt>:only</tt> and
|
24
|
-
# <tt>:except</tt> with an array of actions or a single action:
|
25
|
-
#
|
26
|
-
# respond_to :html
|
27
|
-
# respond_to :xml, :json, except: [ :edit ]
|
28
|
-
#
|
29
|
-
# This specifies that all actions respond to <tt>:html</tt>
|
30
|
-
# and all actions except <tt>:edit</tt> respond to <tt>:xml</tt> and
|
31
|
-
# <tt>:json</tt>.
|
32
|
-
#
|
33
|
-
# respond_to :json, only: :create
|
34
|
-
#
|
35
|
-
# This specifies that the <tt>:create</tt> action and no other responds
|
36
|
-
# to <tt>:json</tt>.
|
37
|
-
def respond_to(*mimes)
|
38
|
-
options = mimes.extract_options!
|
39
|
-
|
40
|
-
only_actions = Array(options.delete(:only)).map(&:to_s)
|
41
|
-
except_actions = Array(options.delete(:except)).map(&:to_s)
|
42
|
-
|
43
|
-
new = mimes_for_respond_to.dup
|
44
|
-
mimes.each do |mime|
|
45
|
-
mime = mime.to_sym
|
46
|
-
new[mime] = {}
|
47
|
-
new[mime][:only] = only_actions unless only_actions.empty?
|
48
|
-
new[mime][:except] = except_actions unless except_actions.empty?
|
49
|
-
end
|
50
|
-
self.mimes_for_respond_to = new.freeze
|
9
|
+
def respond_to(*)
|
10
|
+
raise NoMethodError, "The controller-level `respond_to' feature has " \
|
11
|
+
"been extracted to the `responders` gem. Add it to your Gemfile to " \
|
12
|
+
"continue using this feature:\n" \
|
13
|
+
" gem 'responders', '~> 2.0'\n" \
|
14
|
+
"Consult the Rails upgrade guide for details."
|
51
15
|
end
|
16
|
+
end
|
52
17
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
18
|
+
def respond_with(*)
|
19
|
+
raise NoMethodError, "The `respond_with' feature has been extracted " \
|
20
|
+
"to the `responders` gem. Add it to your Gemfile to continue using " \
|
21
|
+
"this feature:\n" \
|
22
|
+
" gem 'responders', '~> 2.0'\n" \
|
23
|
+
"Consult the Rails upgrade guide for details."
|
58
24
|
end
|
25
|
+
# :startdoc:
|
59
26
|
|
60
27
|
# Without web-service support, an action which collects the data for displaying a list of people
|
61
28
|
# might look something like this:
|
@@ -169,205 +136,85 @@ module ActionController #:nodoc:
|
|
169
136
|
#
|
170
137
|
# render json: @people
|
171
138
|
#
|
172
|
-
#
|
173
|
-
# with the respond_with method to have the same results:
|
139
|
+
# Formats can have different variants.
|
174
140
|
#
|
175
|
-
#
|
176
|
-
#
|
141
|
+
# The request variant is a specialization of the request format, like <tt>:tablet</tt>,
|
142
|
+
# <tt>:phone</tt>, or <tt>:desktop</tt>.
|
177
143
|
#
|
178
|
-
#
|
179
|
-
#
|
180
|
-
# respond_with(@people)
|
181
|
-
# end
|
182
|
-
# end
|
144
|
+
# We often want to render different html/json/xml templates for phones,
|
145
|
+
# tablets, and desktop browsers. Variants make it easy.
|
183
146
|
#
|
184
|
-
#
|
185
|
-
# <tt>ActionController::MimeResponds.respond_to</tt> for more examples.
|
186
|
-
def respond_to(*mimes, &block)
|
187
|
-
raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given?
|
188
|
-
|
189
|
-
if collector = retrieve_collector_from_mimes(mimes, &block)
|
190
|
-
response = collector.response
|
191
|
-
response ? response.call : render({})
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
# For a given controller action, respond_with generates an appropriate
|
196
|
-
# response based on the mime-type requested by the client.
|
147
|
+
# You can set the variant in a +before_action+:
|
197
148
|
#
|
198
|
-
#
|
149
|
+
# request.variant = :tablet if request.user_agent =~ /iPad/
|
199
150
|
#
|
200
|
-
#
|
201
|
-
# respond_to :html, :xml, :json
|
151
|
+
# Respond to variants in the action just like you respond to formats:
|
202
152
|
#
|
203
|
-
#
|
204
|
-
#
|
205
|
-
#
|
153
|
+
# respond_to do |format|
|
154
|
+
# format.html do |variant|
|
155
|
+
# variant.tablet # renders app/views/projects/show.html+tablet.erb
|
156
|
+
# variant.phone { extra_setup; render ... }
|
157
|
+
# variant.none { special_setup } # executed only if there is no variant set
|
206
158
|
# end
|
207
159
|
# end
|
208
160
|
#
|
209
|
-
#
|
210
|
-
# request's Accept header and the set of available formats declared
|
211
|
-
# by previous calls to the controller's class method +respond_to+. Alternatively
|
212
|
-
# the mime-type can be selected by explicitly setting <tt>request.format</tt> in
|
213
|
-
# the controller.
|
214
|
-
#
|
215
|
-
# If an acceptable format is not identified, the application returns a
|
216
|
-
# '406 - not acceptable' status. Otherwise, the default response is to render
|
217
|
-
# a template named after the current action and the selected format,
|
218
|
-
# e.g. <tt>index.html.erb</tt>. If no template is available, the behavior
|
219
|
-
# depends on the selected format:
|
220
|
-
#
|
221
|
-
# * for an html response - if the request method is +get+, an exception
|
222
|
-
# is raised but for other requests such as +post+ the response
|
223
|
-
# depends on whether the resource has any validation errors (i.e.
|
224
|
-
# assuming that an attempt has been made to save the resource,
|
225
|
-
# e.g. by a +create+ action) -
|
226
|
-
# 1. If there are no errors, i.e. the resource
|
227
|
-
# was saved successfully, the response +redirect+'s to the resource
|
228
|
-
# i.e. its +show+ action.
|
229
|
-
# 2. If there are validation errors, the response
|
230
|
-
# renders a default action, which is <tt>:new</tt> for a
|
231
|
-
# +post+ request or <tt>:edit</tt> for +patch+ or +put+.
|
232
|
-
# Thus an example like this -
|
233
|
-
#
|
234
|
-
# respond_to :html, :xml
|
235
|
-
#
|
236
|
-
# def create
|
237
|
-
# @user = User.new(params[:user])
|
238
|
-
# flash[:notice] = 'User was successfully created.' if @user.save
|
239
|
-
# respond_with(@user)
|
240
|
-
# end
|
161
|
+
# Provide separate templates for each format and variant:
|
241
162
|
#
|
242
|
-
#
|
243
|
-
#
|
244
|
-
#
|
245
|
-
# @user = User.new(params[:user])
|
246
|
-
# respond_to do |format|
|
247
|
-
# if @user.save
|
248
|
-
# flash[:notice] = 'User was successfully created.'
|
249
|
-
# format.html { redirect_to(@user) }
|
250
|
-
# format.xml { render xml: @user }
|
251
|
-
# else
|
252
|
-
# format.html { render action: "new" }
|
253
|
-
# format.xml { render xml: @user }
|
254
|
-
# end
|
255
|
-
# end
|
256
|
-
# end
|
163
|
+
# app/views/projects/show.html.erb
|
164
|
+
# app/views/projects/show.html+tablet.erb
|
165
|
+
# app/views/projects/show.html+phone.erb
|
257
166
|
#
|
258
|
-
#
|
259
|
-
#
|
260
|
-
# * for other requests - i.e. data formats such as xml, json, csv etc, if
|
261
|
-
# the resource passed to +respond_with+ responds to <code>to_<format></code>,
|
262
|
-
# the method attempts to render the resource in the requested format
|
263
|
-
# directly, e.g. for an xml request, the response is equivalent to calling
|
264
|
-
# <code>render xml: resource</code>.
|
167
|
+
# When you're not sharing any code within the format, you can simplify defining variants
|
168
|
+
# using the inline syntax:
|
265
169
|
#
|
266
|
-
#
|
170
|
+
# respond_to do |format|
|
171
|
+
# format.js { render "trash" }
|
172
|
+
# format.html.phone { redirect_to progress_path }
|
173
|
+
# format.html.none { render "trash" }
|
174
|
+
# end
|
267
175
|
#
|
268
|
-
#
|
269
|
-
# can play two roles. It can be used to generate the redirect url
|
270
|
-
# for successful html requests (e.g. for +create+ actions when
|
271
|
-
# no template exists), while for formats other than html and javascript
|
272
|
-
# it is the object that gets rendered, by being converted directly to the
|
273
|
-
# required format (again assuming no template exists).
|
176
|
+
# Variants also support common `any`/`all` block that formats have.
|
274
177
|
#
|
275
|
-
#
|
276
|
-
# the use of nested resources, which are supplied in the same way as
|
277
|
-
# in <code>form_for</code> and <code>polymorphic_url</code>. For example -
|
178
|
+
# It works for both inline:
|
278
179
|
#
|
279
|
-
#
|
280
|
-
#
|
281
|
-
#
|
282
|
-
# flash[:notice] = 'Task was successfully created.' if @task.save
|
283
|
-
# respond_with(@project, @task)
|
180
|
+
# respond_to do |format|
|
181
|
+
# format.html.any { render text: "any" }
|
182
|
+
# format.html.phone { render text: "phone" }
|
284
183
|
# end
|
285
184
|
#
|
286
|
-
#
|
287
|
-
# instead of <code>task_url</code>. For request formats other than html or
|
288
|
-
# javascript, if multiple resources are passed in this way, it is the last
|
289
|
-
# one specified that is rendered.
|
185
|
+
# and block syntax:
|
290
186
|
#
|
291
|
-
#
|
187
|
+
# respond_to do |format|
|
188
|
+
# format.html do |variant|
|
189
|
+
# variant.any(:tablet, :phablet){ render text: "any" }
|
190
|
+
# variant.phone { render text: "phone" }
|
191
|
+
# end
|
192
|
+
# end
|
292
193
|
#
|
293
|
-
#
|
294
|
-
# can be used to overwrite any of the default responses, e.g. -
|
194
|
+
# You can also set an array of variants:
|
295
195
|
#
|
296
|
-
#
|
297
|
-
# @user = User.new(params[:user])
|
298
|
-
# flash[:notice] = "User was successfully created." if @user.save
|
196
|
+
# request.variant = [:tablet, :phone]
|
299
197
|
#
|
300
|
-
#
|
301
|
-
#
|
302
|
-
#
|
198
|
+
# which will work similarly to formats and MIME types negotiation. If there will be no
|
199
|
+
# :tablet variant declared, :phone variant will be picked:
|
200
|
+
#
|
201
|
+
# respond_to do |format|
|
202
|
+
# format.html.none
|
203
|
+
# format.html.phone # this gets rendered
|
303
204
|
# end
|
304
205
|
#
|
305
|
-
#
|
306
|
-
#
|
307
|
-
|
308
|
-
|
309
|
-
#
|
310
|
-
# Also, a hash passed to +respond_with+ immediately after the specified
|
311
|
-
# resource(s) is interpreted as a set of options relevant to all
|
312
|
-
# formats. Any option accepted by +render+ can be used, e.g.
|
313
|
-
# respond_with @people, status: 200
|
314
|
-
# However, note that these options are ignored after an unsuccessful attempt
|
315
|
-
# to save a resource, e.g. when automatically rendering <tt>:new</tt>
|
316
|
-
# after a post request.
|
317
|
-
#
|
318
|
-
# Two additional options are relevant specifically to +respond_with+ -
|
319
|
-
# 1. <tt>:location</tt> - overwrites the default redirect location used after
|
320
|
-
# a successful html +post+ request.
|
321
|
-
# 2. <tt>:action</tt> - overwrites the default render action used after an
|
322
|
-
# unsuccessful html +post+ request.
|
323
|
-
def respond_with(*resources, &block)
|
324
|
-
raise "In order to use respond_with, first you need to declare the formats your " \
|
325
|
-
"controller responds to in the class level" if self.class.mimes_for_respond_to.empty?
|
326
|
-
|
327
|
-
if collector = retrieve_collector_from_mimes(&block)
|
328
|
-
options = resources.size == 1 ? {} : resources.extract_options!
|
329
|
-
options[:default_response] = collector.response
|
330
|
-
(options.delete(:responder) || self.class.responder).call(self, resources, options)
|
331
|
-
end
|
332
|
-
end
|
333
|
-
|
334
|
-
protected
|
335
|
-
|
336
|
-
# Collect mimes declared in the class method respond_to valid for the
|
337
|
-
# current action.
|
338
|
-
def collect_mimes_from_class_level #:nodoc:
|
339
|
-
action = action_name.to_s
|
340
|
-
|
341
|
-
self.class.mimes_for_respond_to.keys.select do |mime|
|
342
|
-
config = self.class.mimes_for_respond_to[mime]
|
343
|
-
|
344
|
-
if config[:except]
|
345
|
-
!config[:except].include?(action)
|
346
|
-
elsif config[:only]
|
347
|
-
config[:only].include?(action)
|
348
|
-
else
|
349
|
-
true
|
350
|
-
end
|
351
|
-
end
|
352
|
-
end
|
206
|
+
# Be sure to check the documentation of <tt>ActionController::MimeResponds.respond_to</tt>
|
207
|
+
# for more examples.
|
208
|
+
def respond_to(*mimes)
|
209
|
+
raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given?
|
353
210
|
|
354
|
-
|
355
|
-
|
356
|
-
# In typical usage this is the block passed to +respond_with+ or +respond_to+.
|
357
|
-
#
|
358
|
-
# Sends :not_acceptable to the client and returns nil if no suitable format
|
359
|
-
# is available.
|
360
|
-
def retrieve_collector_from_mimes(mimes=nil, &block) #:nodoc:
|
361
|
-
mimes ||= collect_mimes_from_class_level
|
362
|
-
collector = Collector.new(mimes)
|
363
|
-
block.call(collector) if block_given?
|
364
|
-
format = collector.negotiate_format(request)
|
211
|
+
collector = Collector.new(mimes, request.variant)
|
212
|
+
yield collector if block_given?
|
365
213
|
|
366
|
-
if format
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
collector
|
214
|
+
if format = collector.negotiate_format(request)
|
215
|
+
_process_format(format)
|
216
|
+
response = collector.response
|
217
|
+
response ? response.call : render({})
|
371
218
|
else
|
372
219
|
raise ActionController::UnknownFormat
|
373
220
|
end
|
@@ -376,8 +223,8 @@ module ActionController #:nodoc:
|
|
376
223
|
# A container for responses available from the current controller for
|
377
224
|
# requests for different mime-types sent to a particular action.
|
378
225
|
#
|
379
|
-
# The public controller methods +
|
380
|
-
#
|
226
|
+
# The public controller methods +respond_to+ may be called with a block
|
227
|
+
# that is used to define responses to different mime-types, e.g.
|
381
228
|
# for +respond_to+ :
|
382
229
|
#
|
383
230
|
# respond_to do |format|
|
@@ -397,11 +244,13 @@ module ActionController #:nodoc:
|
|
397
244
|
# request, with this response then being accessible by calling #response.
|
398
245
|
class Collector
|
399
246
|
include AbstractController::Collector
|
400
|
-
attr_accessor :
|
247
|
+
attr_accessor :format
|
248
|
+
|
249
|
+
def initialize(mimes, variant = nil)
|
250
|
+
@responses = {}
|
251
|
+
@variant = variant
|
401
252
|
|
402
|
-
|
403
|
-
@order, @responses = [], {}
|
404
|
-
mimes.each { |mime| send(mime) }
|
253
|
+
mimes.each { |mime| @responses["Mime::#{mime.upcase}".constantize] = nil }
|
405
254
|
end
|
406
255
|
|
407
256
|
def any(*args, &block)
|
@@ -415,16 +264,62 @@ module ActionController #:nodoc:
|
|
415
264
|
|
416
265
|
def custom(mime_type, &block)
|
417
266
|
mime_type = Mime::Type.lookup(mime_type.to_s) unless mime_type.is_a?(Mime::Type)
|
418
|
-
@
|
419
|
-
|
267
|
+
@responses[mime_type] ||= if block_given?
|
268
|
+
block
|
269
|
+
else
|
270
|
+
VariantCollector.new(@variant)
|
271
|
+
end
|
420
272
|
end
|
421
273
|
|
422
274
|
def response
|
423
|
-
@responses.fetch(format, @responses[Mime::ALL])
|
275
|
+
response = @responses.fetch(format, @responses[Mime::ALL])
|
276
|
+
if response.is_a?(VariantCollector) # `format.html.phone` - variant inline syntax
|
277
|
+
response.variant
|
278
|
+
elsif response.nil? || response.arity == 0 # `format.html` - just a format, call its block
|
279
|
+
response
|
280
|
+
else # `format.html{ |variant| variant.phone }` - variant block syntax
|
281
|
+
variant_collector = VariantCollector.new(@variant)
|
282
|
+
response.call(variant_collector) # call format block with variants collector
|
283
|
+
variant_collector.variant
|
284
|
+
end
|
424
285
|
end
|
425
286
|
|
426
287
|
def negotiate_format(request)
|
427
|
-
@format = request.negotiate_mime(
|
288
|
+
@format = request.negotiate_mime(@responses.keys)
|
289
|
+
end
|
290
|
+
|
291
|
+
class VariantCollector #:nodoc:
|
292
|
+
def initialize(variant = nil)
|
293
|
+
@variant = variant
|
294
|
+
@variants = {}
|
295
|
+
end
|
296
|
+
|
297
|
+
def any(*args, &block)
|
298
|
+
if block_given?
|
299
|
+
if args.any? && args.none?{ |a| a == @variant }
|
300
|
+
args.each{ |v| @variants[v] = block }
|
301
|
+
else
|
302
|
+
@variants[:any] = block
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
306
|
+
alias :all :any
|
307
|
+
|
308
|
+
def method_missing(name, *args, &block)
|
309
|
+
@variants[name] = block if block_given?
|
310
|
+
end
|
311
|
+
|
312
|
+
def variant
|
313
|
+
if @variant.nil?
|
314
|
+
@variants[:none] || @variants[:any]
|
315
|
+
elsif (@variants.keys & @variant).any?
|
316
|
+
@variant.each do |v|
|
317
|
+
return @variants[v] if @variants.key?(v)
|
318
|
+
end
|
319
|
+
else
|
320
|
+
@variants[:any]
|
321
|
+
end
|
322
|
+
end
|
428
323
|
end
|
429
324
|
end
|
430
325
|
end
|
@@ -5,8 +5,8 @@ require 'active_support/core_ext/struct'
|
|
5
5
|
require 'action_dispatch/http/mime_type'
|
6
6
|
|
7
7
|
module ActionController
|
8
|
-
# Wraps the parameters hash into a nested hash. This will allow clients to
|
9
|
-
#
|
8
|
+
# Wraps the parameters hash into a nested hash. This will allow clients to
|
9
|
+
# submit requests without having to specify any root elements.
|
10
10
|
#
|
11
11
|
# This functionality is enabled in +config/initializers/wrap_parameters.rb+
|
12
12
|
# and can be customized. If you are upgrading to \Rails 3.1, this file will
|
@@ -16,7 +16,7 @@ module ActionController
|
|
16
16
|
# a non-empty array:
|
17
17
|
#
|
18
18
|
# class UsersController < ApplicationController
|
19
|
-
# wrap_parameters format: [:json, :xml]
|
19
|
+
# wrap_parameters format: [:json, :xml, :url_encoded_form, :multipart_form]
|
20
20
|
# end
|
21
21
|
#
|
22
22
|
# If you enable +ParamsWrapper+ for +:json+ format, instead of having to
|
@@ -231,7 +231,12 @@ module ActionController
|
|
231
231
|
# by the metal call stack.
|
232
232
|
def process_action(*args)
|
233
233
|
if _wrapper_enabled?
|
234
|
-
|
234
|
+
if request.parameters[_wrapper_key].present?
|
235
|
+
wrapped_hash = _extract_parameters(request.parameters)
|
236
|
+
else
|
237
|
+
wrapped_hash = _wrap_parameters request.request_parameters
|
238
|
+
end
|
239
|
+
|
235
240
|
wrapped_keys = request.request_parameters.keys
|
236
241
|
wrapped_filtered_hash = _wrap_parameters request.filtered_parameters.slice(*wrapped_keys)
|
237
242
|
|
@@ -239,7 +244,7 @@ module ActionController
|
|
239
244
|
request.parameters.merge! wrapped_hash
|
240
245
|
request.request_parameters.merge! wrapped_hash
|
241
246
|
|
242
|
-
# This will
|
247
|
+
# This will display the wrapped hash in the log file
|
243
248
|
request.filtered_parameters.merge! wrapped_filtered_hash
|
244
249
|
end
|
245
250
|
super
|
@@ -247,7 +252,7 @@ module ActionController
|
|
247
252
|
|
248
253
|
private
|
249
254
|
|
250
|
-
# Returns the wrapper key which will
|
255
|
+
# Returns the wrapper key which will be used to stored wrapped parameters.
|
251
256
|
def _wrapper_key
|
252
257
|
_wrapper_options.name
|
253
258
|
end
|
@@ -259,14 +264,16 @@ module ActionController
|
|
259
264
|
|
260
265
|
# Returns the list of parameters which will be selected for wrapped.
|
261
266
|
def _wrap_parameters(parameters)
|
262
|
-
|
267
|
+
{ _wrapper_key => _extract_parameters(parameters) }
|
268
|
+
end
|
269
|
+
|
270
|
+
def _extract_parameters(parameters)
|
271
|
+
if include_only = _wrapper_options.include
|
263
272
|
parameters.slice(*include_only)
|
264
273
|
else
|
265
274
|
exclude = _wrapper_options.exclude || []
|
266
275
|
parameters.except(*(exclude + EXCLUDE_PARAMETERS))
|
267
276
|
end
|
268
|
-
|
269
|
-
{ _wrapper_key => value }
|
270
277
|
end
|
271
278
|
|
272
279
|
# Checks if we should perform parameters wrapping.
|
@@ -6,7 +6,7 @@ module ActionController
|
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
8
8
|
delegate :headers, :status=, :location=, :content_type=,
|
9
|
-
:status, :location, :content_type, :to => "@_response"
|
9
|
+
:status, :location, :content_type, :response_code, :to => "@_response"
|
10
10
|
|
11
11
|
def dispatch(action, request)
|
12
12
|
set_response!(request)
|
@@ -14,7 +14,7 @@ module ActionController
|
|
14
14
|
include ActionController::RackDelegation
|
15
15
|
include ActionController::UrlFor
|
16
16
|
|
17
|
-
# Redirects the browser to the target specified in +options+. This parameter can
|
17
|
+
# Redirects the browser to the target specified in +options+. This parameter can be any one of:
|
18
18
|
#
|
19
19
|
# * <tt>Hash</tt> - The URL will be generated by calling url_for with the +options+.
|
20
20
|
# * <tt>Record</tt> - The URL will be generated by calling url_for with the +options+, which will reference a named URL for that record.
|
@@ -24,6 +24,8 @@ module ActionController
|
|
24
24
|
# * <tt>:back</tt> - Back to the page that issued the request. Useful for forms that are triggered from multiple places.
|
25
25
|
# Short-hand for <tt>redirect_to(request.env["HTTP_REFERER"])</tt>
|
26
26
|
#
|
27
|
+
# === Examples:
|
28
|
+
#
|
27
29
|
# redirect_to action: "show", id: 5
|
28
30
|
# redirect_to post
|
29
31
|
# redirect_to "http://www.rubyonrails.org"
|
@@ -32,7 +34,7 @@ module ActionController
|
|
32
34
|
# redirect_to :back
|
33
35
|
# redirect_to proc { edit_post_url(@post) }
|
34
36
|
#
|
35
|
-
# The redirection happens as a "302 Found" header unless otherwise specified
|
37
|
+
# The redirection happens as a "302 Found" header unless otherwise specified using the <tt>:status</tt> option:
|
36
38
|
#
|
37
39
|
# redirect_to post_url(@post), status: :found
|
38
40
|
# redirect_to action: 'atom', status: :moved_permanently
|
@@ -58,18 +60,43 @@ module ActionController
|
|
58
60
|
# redirect_to post_url(@post), alert: "Watch it, mister!"
|
59
61
|
# redirect_to post_url(@post), status: :found, notice: "Pay attention to the road"
|
60
62
|
# redirect_to post_url(@post), status: 301, flash: { updated_post_id: @post.id }
|
61
|
-
# redirect_to
|
63
|
+
# redirect_to({ action: 'atom' }, alert: "Something serious happened")
|
62
64
|
#
|
63
|
-
# When using <tt>redirect_to :back</tt>, if there is no referrer,
|
64
|
-
#
|
65
|
+
# When using <tt>redirect_to :back</tt>, if there is no referrer,
|
66
|
+
# <tt>ActionController::RedirectBackError</tt> will be raised. You
|
67
|
+
# may specify some fallback behavior for this case by rescuing
|
68
|
+
# <tt>ActionController::RedirectBackError</tt>.
|
65
69
|
def redirect_to(options = {}, response_status = {}) #:doc:
|
66
70
|
raise ActionControllerError.new("Cannot redirect to nil!") unless options
|
71
|
+
raise ActionControllerError.new("Cannot redirect to a parameter hash!") if options.is_a?(ActionController::Parameters)
|
67
72
|
raise AbstractController::DoubleRenderError if response_body
|
68
73
|
|
69
74
|
self.status = _extract_redirect_to_status(options, response_status)
|
70
|
-
self.location = _compute_redirect_to_location(options)
|
71
|
-
self.response_body = "<html><body>You are being <a href=\"#{ERB::Util.
|
75
|
+
self.location = _compute_redirect_to_location(request, options)
|
76
|
+
self.response_body = "<html><body>You are being <a href=\"#{ERB::Util.unwrapped_html_escape(location)}\">redirected</a>.</body></html>"
|
77
|
+
end
|
78
|
+
|
79
|
+
def _compute_redirect_to_location(request, options) #:nodoc:
|
80
|
+
case options
|
81
|
+
# The scheme name consist of a letter followed by any combination of
|
82
|
+
# letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
|
83
|
+
# characters; and is terminated by a colon (":").
|
84
|
+
# See http://tools.ietf.org/html/rfc3986#section-3.1
|
85
|
+
# The protocol relative scheme starts with a double slash "//".
|
86
|
+
when /\A([a-z][a-z\d\-+\.]*:|\/\/).*/i
|
87
|
+
options
|
88
|
+
when String
|
89
|
+
request.protocol + request.host_with_port + options
|
90
|
+
when :back
|
91
|
+
request.headers["Referer"] or raise RedirectBackError
|
92
|
+
when Proc
|
93
|
+
_compute_redirect_to_location request, options.call
|
94
|
+
else
|
95
|
+
url_for(options)
|
96
|
+
end.delete("\0\r\n")
|
72
97
|
end
|
98
|
+
module_function :_compute_redirect_to_location
|
99
|
+
public :_compute_redirect_to_location
|
73
100
|
|
74
101
|
private
|
75
102
|
def _extract_redirect_to_status(options, response_status)
|
@@ -81,24 +108,5 @@ module ActionController
|
|
81
108
|
302
|
82
109
|
end
|
83
110
|
end
|
84
|
-
|
85
|
-
def _compute_redirect_to_location(options)
|
86
|
-
case options
|
87
|
-
# The scheme name consist of a letter followed by any combination of
|
88
|
-
# letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
|
89
|
-
# characters; and is terminated by a colon (":").
|
90
|
-
# The protocol relative scheme starts with a double slash "//"
|
91
|
-
when %r{\A(\w[\w+.-]*:|//).*}
|
92
|
-
options
|
93
|
-
when String
|
94
|
-
request.protocol + request.host_with_port + options
|
95
|
-
when :back
|
96
|
-
request.headers["Referer"] or raise RedirectBackError
|
97
|
-
when Proc
|
98
|
-
_compute_redirect_to_location options.call
|
99
|
-
else
|
100
|
-
url_for(options)
|
101
|
-
end.delete("\0\r\n")
|
102
|
-
end
|
103
111
|
end
|
104
112
|
end
|