actionpack 3.0.20 → 3.1.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.
- data/CHANGELOG +88 -142
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -6
- data/lib/abstract_controller.rb +1 -0
- data/lib/abstract_controller/asset_paths.rb +2 -2
- data/lib/abstract_controller/base.rb +24 -19
- data/lib/abstract_controller/callbacks.rb +19 -19
- data/lib/abstract_controller/helpers.rb +11 -13
- data/lib/abstract_controller/layouts.rb +4 -5
- data/lib/abstract_controller/railties/routes_helpers.rb +18 -0
- data/lib/abstract_controller/rendering.rb +34 -31
- data/lib/abstract_controller/url_for.rb +27 -0
- data/lib/abstract_controller/view_paths.rb +31 -6
- data/lib/action_controller.rb +5 -3
- data/lib/action_controller/base.rb +15 -16
- data/lib/action_controller/caching.rb +2 -2
- data/lib/action_controller/caching/actions.rb +11 -12
- data/lib/action_controller/caching/fragments.rb +41 -19
- data/lib/action_controller/caching/pages.rb +3 -9
- data/lib/action_controller/caching/sweeping.rb +0 -1
- data/lib/action_controller/deprecated.rb +1 -1
- data/lib/action_controller/log_subscriber.rb +1 -1
- data/lib/action_controller/metal.rb +78 -20
- data/lib/action_controller/metal/compatibility.rb +0 -9
- data/lib/action_controller/metal/conditional_get.rb +9 -9
- data/lib/action_controller/metal/data_streaming.rb +145 -0
- data/lib/action_controller/metal/force_ssl.rb +35 -0
- data/lib/action_controller/metal/head.rb +1 -1
- data/lib/action_controller/metal/helpers.rb +37 -44
- data/lib/action_controller/metal/hide_actions.rb +2 -3
- data/lib/action_controller/metal/http_authentication.rb +41 -38
- data/lib/action_controller/metal/implicit_render.rb +13 -13
- data/lib/action_controller/metal/instrumentation.rb +2 -2
- data/lib/action_controller/metal/mime_responds.rb +25 -19
- data/lib/action_controller/metal/params_wrapper.rb +224 -0
- data/lib/action_controller/metal/redirecting.rb +6 -2
- data/lib/action_controller/metal/renderers.rb +50 -36
- data/lib/action_controller/metal/rendering.rb +34 -25
- data/lib/action_controller/metal/request_forgery_protection.rb +18 -36
- data/lib/action_controller/metal/responder.rb +47 -12
- data/lib/action_controller/metal/streaming.rb +244 -138
- data/lib/action_controller/metal/testing.rb +0 -9
- data/lib/action_controller/metal/url_for.rb +12 -14
- data/lib/action_controller/railtie.rb +19 -37
- data/lib/action_controller/railties/paths.rb +24 -0
- data/lib/action_controller/record_identifier.rb +4 -10
- data/lib/action_controller/test_case.rb +36 -19
- data/lib/action_controller/vendor/html-scanner/html/node.rb +5 -5
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +3 -3
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +2 -0
- data/lib/action_dispatch.rb +4 -1
- data/lib/action_dispatch/http/cache.rb +5 -32
- data/lib/action_dispatch/http/filter_parameters.rb +3 -1
- data/lib/action_dispatch/http/mime_negotiation.rb +22 -3
- data/lib/action_dispatch/http/mime_type.rb +45 -5
- data/lib/action_dispatch/http/rack_cache.rb +58 -0
- data/lib/action_dispatch/http/request.rb +27 -41
- data/lib/action_dispatch/http/response.rb +56 -54
- data/lib/action_dispatch/http/upload.rb +1 -11
- data/lib/action_dispatch/http/url.rb +102 -42
- data/lib/action_dispatch/middleware/callbacks.rb +8 -25
- data/lib/action_dispatch/middleware/closed_error.rb +7 -0
- data/lib/action_dispatch/middleware/cookies.rb +37 -15
- data/lib/action_dispatch/middleware/flash.rb +80 -11
- data/lib/action_dispatch/middleware/params_parser.rb +2 -2
- data/lib/action_dispatch/middleware/reloader.rb +76 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +56 -226
- data/lib/action_dispatch/middleware/session/cookie_store.rb +20 -44
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -46
- data/lib/action_dispatch/middleware/show_exceptions.rb +15 -2
- data/lib/action_dispatch/middleware/stack.rb +50 -17
- data/lib/action_dispatch/middleware/static.rb +41 -29
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +4 -2
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +2 -6
- data/lib/action_dispatch/railtie.rb +8 -0
- data/lib/action_dispatch/routing.rb +13 -1
- data/lib/action_dispatch/routing/mapper.rb +345 -227
- data/lib/action_dispatch/routing/polymorphic_routes.rb +33 -13
- data/lib/action_dispatch/routing/redirection.rb +110 -0
- data/lib/action_dispatch/routing/route.rb +15 -13
- data/lib/action_dispatch/routing/route_set.rb +116 -90
- data/lib/action_dispatch/routing/routes_proxy.rb +35 -0
- data/lib/action_dispatch/routing/url_for.rb +25 -1
- data/lib/action_dispatch/testing/assertions/response.rb +8 -10
- data/lib/action_dispatch/testing/assertions/routing.rb +15 -15
- data/lib/action_dispatch/testing/assertions/selector.rb +13 -220
- data/lib/action_dispatch/testing/integration.rb +37 -28
- data/lib/action_dispatch/testing/performance_test.rb +1 -3
- data/lib/action_dispatch/testing/test_process.rb +1 -1
- data/lib/action_dispatch/testing/test_request.rb +9 -3
- data/lib/action_dispatch/testing/test_response.rb +4 -111
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +3 -3
- data/lib/action_view.rb +39 -24
- data/lib/action_view/base.rb +61 -86
- data/lib/action_view/buffers.rb +43 -0
- data/lib/action_view/context.rb +21 -24
- data/lib/action_view/flows.rb +79 -0
- data/lib/action_view/helpers.rb +8 -6
- data/lib/action_view/helpers/active_model_helper.rb +0 -23
- data/lib/action_view/helpers/asset_paths.rb +79 -0
- data/lib/action_view/helpers/asset_tag_helper.rb +30 -500
- data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +147 -0
- data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +101 -0
- data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +200 -0
- data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +152 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +2 -2
- data/lib/action_view/helpers/cache_helper.rb +11 -19
- data/lib/action_view/helpers/capture_helper.rb +19 -8
- data/lib/action_view/helpers/controller_helper.rb +21 -0
- data/lib/action_view/helpers/csrf_helper.rb +22 -4
- data/lib/action_view/helpers/date_helper.rb +36 -22
- data/lib/action_view/helpers/form_helper.rb +199 -113
- data/lib/action_view/helpers/form_options_helper.rb +10 -11
- data/lib/action_view/helpers/form_tag_helper.rb +94 -22
- data/lib/action_view/helpers/javascript_helper.rb +24 -107
- data/lib/action_view/helpers/number_helper.rb +36 -33
- data/lib/action_view/helpers/output_safety_helper.rb +38 -0
- data/lib/action_view/helpers/record_tag_helper.rb +6 -6
- data/lib/action_view/helpers/rendering_helper.rb +90 -0
- data/lib/action_view/helpers/sanitize_helper.rb +2 -2
- data/lib/action_view/helpers/sprockets_helper.rb +69 -0
- data/lib/action_view/helpers/tag_helper.rb +34 -12
- data/lib/action_view/helpers/text_helper.rb +30 -145
- data/lib/action_view/helpers/translation_helper.rb +10 -17
- data/lib/action_view/helpers/url_helper.rb +70 -67
- data/lib/action_view/locale/en.yml +1 -1
- data/lib/action_view/lookup_context.rb +36 -14
- data/lib/action_view/{paths.rb → path_set.rb} +9 -8
- data/lib/action_view/railtie.rb +12 -4
- data/lib/action_view/renderer/abstract_renderer.rb +36 -0
- data/lib/action_view/{render/partials.rb → renderer/partial_renderer.rb} +147 -146
- data/lib/action_view/renderer/renderer.rb +54 -0
- data/lib/action_view/renderer/streaming_template_renderer.rb +106 -0
- data/lib/action_view/renderer/template_renderer.rb +74 -0
- data/lib/action_view/template.rb +91 -54
- data/lib/action_view/template/error.rb +11 -8
- data/lib/action_view/template/handler.rb +9 -1
- data/lib/action_view/template/handlers.rb +9 -9
- data/lib/action_view/template/handlers/builder.rb +4 -4
- data/lib/action_view/template/handlers/erb.rb +21 -41
- data/lib/action_view/template/resolver.rb +171 -57
- data/lib/action_view/template/text.rb +0 -4
- data/lib/action_view/test_case.rb +32 -16
- data/lib/action_view/testing/resolvers.rb +16 -10
- data/lib/sprockets/railtie.rb +100 -0
- metadata +162 -140
- checksums.yaml +0 -7
- data/lib/action_controller/deprecated/base.rb +0 -143
- data/lib/action_controller/deprecated/dispatcher.rb +0 -28
- data/lib/action_controller/deprecated/url_writer.rb +0 -14
- data/lib/action_dispatch/routing/deprecated_mapper.rb +0 -525
- data/lib/action_view/helpers/prototype_helper.rb +0 -851
- data/lib/action_view/helpers/raw_output_helper.rb +0 -18
- data/lib/action_view/helpers/scriptaculous_helper.rb +0 -263
- data/lib/action_view/render/layouts.rb +0 -83
- data/lib/action_view/render/rendering.rb +0 -67
- data/lib/action_view/template/handlers/rjs.rb +0 -17
@@ -1,21 +1,21 @@
|
|
1
1
|
module ActionController
|
2
2
|
module ImplicitRender
|
3
|
-
def send_action(*)
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
def send_action(method, *args)
|
4
|
+
if respond_to?(method, true)
|
5
|
+
ret = super
|
6
|
+
default_render unless response_body
|
7
|
+
ret
|
8
|
+
else
|
9
|
+
default_render
|
10
|
+
end
|
7
11
|
end
|
8
12
|
|
9
|
-
def default_render
|
10
|
-
render
|
13
|
+
def default_render(*args)
|
14
|
+
render(*args)
|
11
15
|
end
|
12
16
|
|
13
|
-
def
|
14
|
-
super ||
|
15
|
-
if template_exists?(action_name.to_s, _prefix)
|
16
|
-
"default_render"
|
17
|
-
end
|
18
|
-
end
|
17
|
+
def action_method?(action_name)
|
18
|
+
super || template_exists?(action_name.to_s, _prefixes)
|
19
19
|
end
|
20
20
|
end
|
21
|
-
end
|
21
|
+
end
|
@@ -14,7 +14,7 @@ module ActionController
|
|
14
14
|
|
15
15
|
attr_internal :view_runtime
|
16
16
|
|
17
|
-
def process_action(
|
17
|
+
def process_action(*args)
|
18
18
|
raw_payload = {
|
19
19
|
:controller => self.class.name,
|
20
20
|
:action => self.action_name,
|
@@ -78,7 +78,7 @@ module ActionController
|
|
78
78
|
yield
|
79
79
|
end
|
80
80
|
|
81
|
-
#
|
81
|
+
# Every time after an action is processed, this method is invoked
|
82
82
|
# with the payload, so you can add more information.
|
83
83
|
# :api: plugin
|
84
84
|
def append_info_to_payload(payload) #:nodoc:
|
@@ -1,10 +1,13 @@
|
|
1
1
|
require 'abstract_controller/collector'
|
2
2
|
require 'active_support/core_ext/class/attribute'
|
3
|
+
require 'active_support/core_ext/object/inclusion'
|
3
4
|
|
4
5
|
module ActionController #:nodoc:
|
5
|
-
module MimeResponds
|
6
|
+
module MimeResponds
|
6
7
|
extend ActiveSupport::Concern
|
7
8
|
|
9
|
+
include ActionController::ImplicitRender
|
10
|
+
|
8
11
|
included do
|
9
12
|
class_attribute :responder, :mimes_for_respond_to
|
10
13
|
self.responder = ActionController::Responder
|
@@ -32,10 +35,10 @@ module ActionController #:nodoc:
|
|
32
35
|
# and all actions except <tt>:edit</tt> respond to <tt>:xml</tt> and
|
33
36
|
# <tt>:json</tt>.
|
34
37
|
#
|
35
|
-
# respond_to :
|
38
|
+
# respond_to :json, :only => :create
|
36
39
|
#
|
37
40
|
# This specifies that the <tt>:create</tt> action and no other responds
|
38
|
-
# to <tt>:
|
41
|
+
# to <tt>:json</tt>.
|
39
42
|
def respond_to(*mimes)
|
40
43
|
options = mimes.extract_options!
|
41
44
|
|
@@ -63,13 +66,13 @@ module ActionController #:nodoc:
|
|
63
66
|
# might look something like this:
|
64
67
|
#
|
65
68
|
# def index
|
66
|
-
# @people = Person.
|
69
|
+
# @people = Person.all
|
67
70
|
# end
|
68
71
|
#
|
69
72
|
# Here's the same action, with web-service support baked in:
|
70
73
|
#
|
71
74
|
# def index
|
72
|
-
# @people = Person.
|
75
|
+
# @people = Person.all
|
73
76
|
#
|
74
77
|
# respond_to do |format|
|
75
78
|
# format.html
|
@@ -105,8 +108,8 @@ module ActionController #:nodoc:
|
|
105
108
|
# end
|
106
109
|
# end
|
107
110
|
#
|
108
|
-
# If the client wants HTML, we just redirect them back to the person list. If they want
|
109
|
-
#
|
111
|
+
# If the client wants HTML, we just redirect them back to the person list. If they want JavaScript,
|
112
|
+
# then it is an Ajax request and we render the JavaScript template associated with this action.
|
110
113
|
# Lastly, if the client wants XML, we render the created person as XML, but with a twist: we also
|
111
114
|
# include the person's company in the rendered XML, so you get something like this:
|
112
115
|
#
|
@@ -155,7 +158,7 @@ module ActionController #:nodoc:
|
|
155
158
|
# Respond to also allows you to specify a common block for different formats by using any:
|
156
159
|
#
|
157
160
|
# def index
|
158
|
-
# @people = Person.
|
161
|
+
# @people = Person.all
|
159
162
|
#
|
160
163
|
# respond_to do |format|
|
161
164
|
# format.html
|
@@ -178,7 +181,7 @@ module ActionController #:nodoc:
|
|
178
181
|
# respond_to :html, :xml, :json
|
179
182
|
#
|
180
183
|
# def index
|
181
|
-
# @people = Person.
|
184
|
+
# @people = Person.all
|
182
185
|
# respond_with(@person)
|
183
186
|
# end
|
184
187
|
# end
|
@@ -189,7 +192,7 @@ module ActionController #:nodoc:
|
|
189
192
|
raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given?
|
190
193
|
|
191
194
|
if response = retrieve_response_from_mimes(mimes, &block)
|
192
|
-
response.call
|
195
|
+
response.call(nil)
|
193
196
|
end
|
194
197
|
end
|
195
198
|
|
@@ -208,8 +211,8 @@ module ActionController #:nodoc:
|
|
208
211
|
# It also accepts a block to be given. It's used to overwrite a default
|
209
212
|
# response:
|
210
213
|
#
|
211
|
-
# def
|
212
|
-
# @user = User.
|
214
|
+
# def create
|
215
|
+
# @user = User.new(params[:user])
|
213
216
|
# flash[:notice] = "User was successfully created." if @user.save
|
214
217
|
#
|
215
218
|
# respond_with(@user) do |format|
|
@@ -222,6 +225,9 @@ module ActionController #:nodoc:
|
|
222
225
|
# is quite simple (it just needs to respond to call), you can even give
|
223
226
|
# a proc to it.
|
224
227
|
#
|
228
|
+
# In order to use respond_with, first you need to declare the formats your
|
229
|
+
# controller responds to in the class level with a call to <tt>respond_to</tt>.
|
230
|
+
#
|
225
231
|
def respond_with(*resources, &block)
|
226
232
|
raise "In order to use respond_with, first you need to declare the formats your " <<
|
227
233
|
"controller responds to in the class level" if self.class.mimes_for_respond_to.empty?
|
@@ -245,9 +251,9 @@ module ActionController #:nodoc:
|
|
245
251
|
config = self.class.mimes_for_respond_to[mime]
|
246
252
|
|
247
253
|
if config[:except]
|
248
|
-
!config[:except]
|
254
|
+
!action.in?(config[:except])
|
249
255
|
elsif config[:only]
|
250
|
-
config[:only]
|
256
|
+
action.in?(config[:only])
|
251
257
|
else
|
252
258
|
true
|
253
259
|
end
|
@@ -257,10 +263,9 @@ module ActionController #:nodoc:
|
|
257
263
|
# Collects mimes and return the response for the negotiated format. Returns
|
258
264
|
# nil if :not_acceptable was sent to the client.
|
259
265
|
#
|
260
|
-
def retrieve_response_from_mimes(mimes=nil, &block)
|
261
|
-
collector = Collector.new { default_render }
|
266
|
+
def retrieve_response_from_mimes(mimes=nil, &block) #:nodoc:
|
262
267
|
mimes ||= collect_mimes_from_class_level
|
263
|
-
mimes
|
268
|
+
collector = Collector.new(mimes) { |options| default_render(options || {}) }
|
264
269
|
block.call(collector) if block_given?
|
265
270
|
|
266
271
|
if format = request.negotiate_mime(collector.order)
|
@@ -277,8 +282,9 @@ module ActionController #:nodoc:
|
|
277
282
|
include AbstractController::Collector
|
278
283
|
attr_accessor :order
|
279
284
|
|
280
|
-
def initialize(&block)
|
285
|
+
def initialize(mimes, &block)
|
281
286
|
@order, @responses, @default_response = [], {}, block
|
287
|
+
mimes.each { |mime| send(mime) }
|
282
288
|
end
|
283
289
|
|
284
290
|
def any(*args, &block)
|
@@ -291,7 +297,7 @@ module ActionController #:nodoc:
|
|
291
297
|
alias :all :any
|
292
298
|
|
293
299
|
def custom(mime_type, &block)
|
294
|
-
mime_type =
|
300
|
+
mime_type = Mime::Type.lookup(mime_type.to_s) unless mime_type.is_a?(Mime::Type)
|
295
301
|
@order << mime_type
|
296
302
|
@responses[mime_type] ||= block
|
297
303
|
end
|
@@ -0,0 +1,224 @@
|
|
1
|
+
require 'active_support/core_ext/class/attribute'
|
2
|
+
require 'active_support/core_ext/hash/slice'
|
3
|
+
require 'active_support/core_ext/hash/except'
|
4
|
+
require 'active_support/core_ext/array/wrap'
|
5
|
+
require 'action_dispatch/http/mime_types'
|
6
|
+
|
7
|
+
module ActionController
|
8
|
+
# Wraps parameters hash into nested hash. This will allow client to submit
|
9
|
+
# POST request without having to specify a root element in it.
|
10
|
+
#
|
11
|
+
# By default this functionality won't be enabled. You can enable
|
12
|
+
# it globally by setting +ActionController::Base.wrap_parameters+:
|
13
|
+
#
|
14
|
+
# ActionController::Base.wrap_parameters = [:json]
|
15
|
+
#
|
16
|
+
# You could also turn it on per controller by setting the format array to
|
17
|
+
# non-empty array:
|
18
|
+
#
|
19
|
+
# class UsersController < ApplicationController
|
20
|
+
# wrap_parameters :format => [:json, :xml]
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# If you enable +ParamsWrapper+ for +:json+ format. Instead of having to
|
24
|
+
# send JSON parameters like this:
|
25
|
+
#
|
26
|
+
# {"user": {"name": "Konata"}}
|
27
|
+
#
|
28
|
+
# You can now just send a parameters like this:
|
29
|
+
#
|
30
|
+
# {"name": "Konata"}
|
31
|
+
#
|
32
|
+
# And it will be wrapped into a nested hash with the key name matching
|
33
|
+
# controller's name. For example, if you're posting to +UsersController+,
|
34
|
+
# your new +params+ hash will look like this:
|
35
|
+
#
|
36
|
+
# {"name" => "Konata", "user" => {"name" => "Konata"}}
|
37
|
+
#
|
38
|
+
# You can also specify the key in which the parameters should be wrapped to,
|
39
|
+
# and also the list of attributes it should wrap by using either +:only+ or
|
40
|
+
# +:except+ options like this:
|
41
|
+
#
|
42
|
+
# class UsersController < ApplicationController
|
43
|
+
# wrap_parameters :person, :only => [:username, :password]
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# If you're going to pass the parameters to an +ActiveModel+ object (such as
|
47
|
+
# +User.new(params[:user])+), you might consider passing the model class to
|
48
|
+
# the method instead. The +ParamsWrapper+ will actually try to determine the
|
49
|
+
# list of attribute names from the model and only wrap those attributes:
|
50
|
+
#
|
51
|
+
# class UsersController < ApplicationController
|
52
|
+
# wrap_parameters Person
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# You still could pass +:only+ and +:except+ to set the list of attributes
|
56
|
+
# you want to wrap.
|
57
|
+
#
|
58
|
+
# By default, if you don't specify the key in which the parameters would be
|
59
|
+
# wrapped to, +ParamsWrapper+ will actually try to determine if there's
|
60
|
+
# a model related to it or not. This controller, for example:
|
61
|
+
#
|
62
|
+
# class Admin::UsersController < ApplicationController
|
63
|
+
# end
|
64
|
+
#
|
65
|
+
# will try to check if +Admin::User+ or +User+ model exists, and use it to
|
66
|
+
# determine the wrapper key respectively. If both of the model doesn't exists,
|
67
|
+
# it will then fallback to use +user+ as the key.
|
68
|
+
module ParamsWrapper
|
69
|
+
extend ActiveSupport::Concern
|
70
|
+
|
71
|
+
EXCLUDE_PARAMETERS = %w(authenticity_token _method utf8)
|
72
|
+
|
73
|
+
included do
|
74
|
+
class_attribute :_wrapper_options
|
75
|
+
self._wrapper_options = {:format => []}
|
76
|
+
end
|
77
|
+
|
78
|
+
module ClassMethods
|
79
|
+
# Sets the name of the wrapper key, or the model which +ParamsWrapper+
|
80
|
+
# would use to determine the attribute names from.
|
81
|
+
#
|
82
|
+
# ==== Examples
|
83
|
+
# wrap_parameters :format => :xml
|
84
|
+
# # enables the parmeter wrapper for XML format
|
85
|
+
#
|
86
|
+
# wrap_parameters :person
|
87
|
+
# # wraps parameters into +params[:person]+ hash
|
88
|
+
#
|
89
|
+
# wrap_parameters Person
|
90
|
+
# # wraps parameters by determine the wrapper key from Person class
|
91
|
+
# (+person+, in this case) and the list of attribute names
|
92
|
+
#
|
93
|
+
# wrap_parameters :only => [:username, :title]
|
94
|
+
# # wraps only +:username+ and +:title+ attributes from parameters.
|
95
|
+
#
|
96
|
+
# wrap_parameters false
|
97
|
+
# # disable parameters wrapping for this controller altogether.
|
98
|
+
#
|
99
|
+
# ==== Options
|
100
|
+
# * <tt>:format</tt> - The list of formats in which the parameters wrapper
|
101
|
+
# will be enabled.
|
102
|
+
# * <tt>:only</tt> - The list of attribute names which parameters wrapper
|
103
|
+
# will wrap into a nested hash.
|
104
|
+
# * <tt>:except</tt> - The list of attribute names which parameters wrapper
|
105
|
+
# will exclude from a nested hash.
|
106
|
+
def wrap_parameters(name_or_model_or_options, options = {})
|
107
|
+
model = nil
|
108
|
+
|
109
|
+
case name_or_model_or_options
|
110
|
+
when Hash
|
111
|
+
options = name_or_model_or_options
|
112
|
+
when false
|
113
|
+
options = options.merge(:format => [])
|
114
|
+
when Symbol, String
|
115
|
+
options = options.merge(:name => name_or_model_or_options)
|
116
|
+
else
|
117
|
+
model = name_or_model_or_options
|
118
|
+
end
|
119
|
+
|
120
|
+
_set_wrapper_defaults(_wrapper_options.slice(:format).merge(options), model)
|
121
|
+
end
|
122
|
+
|
123
|
+
# Sets the default wrapper key or model which will be used to determine
|
124
|
+
# wrapper key and attribute names. Will be called automatically when the
|
125
|
+
# module is inherited.
|
126
|
+
def inherited(klass)
|
127
|
+
if klass._wrapper_options[:format].present?
|
128
|
+
klass._set_wrapper_defaults(klass._wrapper_options)
|
129
|
+
end
|
130
|
+
super
|
131
|
+
end
|
132
|
+
|
133
|
+
protected
|
134
|
+
|
135
|
+
# Determine the wrapper model from the controller's name. By convention,
|
136
|
+
# this could be done by trying to find the defined model that has the
|
137
|
+
# same singularize name as the controller. For example, +UsersController+
|
138
|
+
# will try to find if the +User+ model exists.
|
139
|
+
def _default_wrap_model
|
140
|
+
model_name = self.name.sub(/Controller$/, '').singularize
|
141
|
+
|
142
|
+
begin
|
143
|
+
model_klass = model_name.constantize
|
144
|
+
rescue NameError => e
|
145
|
+
unscoped_model_name = model_name.split("::", 2).last
|
146
|
+
break if unscoped_model_name == model_name
|
147
|
+
model_name = unscoped_model_name
|
148
|
+
end until model_klass
|
149
|
+
|
150
|
+
model_klass
|
151
|
+
end
|
152
|
+
|
153
|
+
def _set_wrapper_defaults(options, model=nil)
|
154
|
+
options = options.dup
|
155
|
+
|
156
|
+
unless options[:only] || options[:except]
|
157
|
+
model ||= _default_wrap_model
|
158
|
+
if model.respond_to?(:column_names)
|
159
|
+
options[:only] = model.column_names
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
unless options[:name]
|
164
|
+
model ||= _default_wrap_model
|
165
|
+
options[:name] = model ? model.to_s.demodulize.underscore :
|
166
|
+
controller_name.singularize
|
167
|
+
end
|
168
|
+
|
169
|
+
options[:only] = Array.wrap(options[:only]).collect(&:to_s) if options[:only]
|
170
|
+
options[:except] = Array.wrap(options[:except]).collect(&:to_s) if options[:except]
|
171
|
+
options[:format] = Array.wrap(options[:format])
|
172
|
+
|
173
|
+
self._wrapper_options = options
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# Performs parameters wrapping upon the request. Will be called automatically
|
178
|
+
# by the metal call stack.
|
179
|
+
def process_action(*args)
|
180
|
+
if _wrapper_enabled?
|
181
|
+
wrapped_hash = _wrap_parameters request.request_parameters
|
182
|
+
wrapped_filtered_hash = _wrap_parameters request.filtered_parameters
|
183
|
+
|
184
|
+
# This will make the wrapped hash accessible from controller and view
|
185
|
+
request.parameters.merge! wrapped_hash
|
186
|
+
request.request_parameters.merge! wrapped_hash
|
187
|
+
|
188
|
+
# This will make the wrapped hash displayed in the log file
|
189
|
+
request.filtered_parameters.merge! wrapped_filtered_hash
|
190
|
+
end
|
191
|
+
super
|
192
|
+
end
|
193
|
+
|
194
|
+
private
|
195
|
+
|
196
|
+
# Returns the wrapper key which will use to stored wrapped parameters.
|
197
|
+
def _wrapper_key
|
198
|
+
_wrapper_options[:name]
|
199
|
+
end
|
200
|
+
|
201
|
+
# Returns the list of enabled formats.
|
202
|
+
def _wrapper_formats
|
203
|
+
_wrapper_options[:format]
|
204
|
+
end
|
205
|
+
|
206
|
+
# Returns the list of parameters which will be selected for wrapped.
|
207
|
+
def _wrap_parameters(parameters)
|
208
|
+
value = if only = _wrapper_options[:only]
|
209
|
+
parameters.slice(*only)
|
210
|
+
else
|
211
|
+
except = _wrapper_options[:except] || []
|
212
|
+
parameters.except(*(except + EXCLUDE_PARAMETERS))
|
213
|
+
end
|
214
|
+
|
215
|
+
{ _wrapper_key => value }
|
216
|
+
end
|
217
|
+
|
218
|
+
# Checks if we should perform parameters wrapping.
|
219
|
+
def _wrapper_enabled?
|
220
|
+
ref = request.content_mime_type.try(:ref)
|
221
|
+
_wrapper_formats.include?(ref) && !request.request_parameters[_wrapper_key]
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
@@ -20,6 +20,7 @@ module ActionController
|
|
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.
|
21
21
|
# * <tt>String</tt> starting with <tt>protocol://</tt> (like <tt>http://</tt>) - Is passed straight through as the target for redirection.
|
22
22
|
# * <tt>String</tt> not containing a protocol - The current protocol and host is prepended to the string.
|
23
|
+
# * <tt>Proc</tt> - A block that will be executed in the controller's context. Should return any option accepted by +redirect_to+.
|
23
24
|
# * <tt>:back</tt> - Back to the page that issued the request. Useful for forms that are triggered from multiple places.
|
24
25
|
# Short-hand for <tt>redirect_to(request.env["HTTP_REFERER"])</tt>
|
25
26
|
#
|
@@ -30,6 +31,7 @@ module ActionController
|
|
30
31
|
# redirect_to "/images/screenshot.jpg"
|
31
32
|
# redirect_to articles_url
|
32
33
|
# redirect_to :back
|
34
|
+
# redirect_to proc { edit_post_url(@post) }
|
33
35
|
#
|
34
36
|
# The redirection happens as a "302 Moved" header unless otherwise specified.
|
35
37
|
#
|
@@ -38,7 +40,7 @@ module ActionController
|
|
38
40
|
# redirect_to :action=>'atom', :status => :moved_permanently
|
39
41
|
# redirect_to post_url(@post), :status => 301
|
40
42
|
# redirect_to :action=>'atom', :status => 302
|
41
|
-
#
|
43
|
+
#
|
42
44
|
# The status code can either be a standard {HTTP Status code}[http://www.iana.org/assignments/http-status-codes] as an
|
43
45
|
# integer, or a symbol representing the downcased, underscored and symbolized description.
|
44
46
|
#
|
@@ -85,9 +87,11 @@ module ActionController
|
|
85
87
|
when :back
|
86
88
|
raise RedirectBackError unless refer = request.headers["Referer"]
|
87
89
|
refer
|
90
|
+
when Proc
|
91
|
+
_compute_redirect_to_location options.call
|
88
92
|
else
|
89
93
|
url_for(options)
|
90
|
-
end.gsub(/[\
|
94
|
+
end.gsub(/[\r\n]/, '')
|
91
95
|
end
|
92
96
|
end
|
93
97
|
end
|