actionpack 1.9.1 → 1.10.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.
- data/CHANGELOG +237 -0
- data/README +12 -12
- data/lib/action_controller.rb +17 -12
- data/lib/action_controller/assertions.rb +119 -67
- data/lib/action_controller/base.rb +184 -102
- data/lib/action_controller/benchmarking.rb +35 -6
- data/lib/action_controller/caching.rb +115 -58
- data/lib/action_controller/cgi_ext/cgi_methods.rb +54 -21
- data/lib/action_controller/cgi_ext/cookie_performance_fix.rb +39 -35
- data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +34 -21
- data/lib/action_controller/cgi_process.rb +23 -20
- data/lib/action_controller/components.rb +11 -2
- data/lib/action_controller/dependencies.rb +0 -5
- data/lib/action_controller/deprecated_redirects.rb +17 -0
- data/lib/action_controller/filters.rb +13 -9
- data/lib/action_controller/flash.rb +7 -7
- data/lib/action_controller/helpers.rb +1 -14
- data/lib/action_controller/layout.rb +40 -29
- data/lib/action_controller/macros/auto_complete.rb +52 -0
- data/lib/action_controller/macros/in_place_editing.rb +32 -0
- data/lib/action_controller/pagination.rb +44 -28
- data/lib/action_controller/request.rb +54 -40
- data/lib/action_controller/rescue.rb +8 -6
- data/lib/action_controller/routing.rb +77 -28
- data/lib/action_controller/scaffolding.rb +10 -14
- data/lib/action_controller/session/active_record_store.rb +36 -7
- data/lib/action_controller/session_management.rb +126 -0
- data/lib/action_controller/streaming.rb +14 -5
- data/lib/action_controller/templates/rescues/_request_and_response.rhtml +1 -1
- data/lib/action_controller/templates/rescues/_trace.rhtml +24 -0
- data/lib/action_controller/templates/rescues/diagnostics.rhtml +2 -13
- data/lib/action_controller/templates/rescues/template_error.rhtml +4 -2
- data/lib/action_controller/templates/scaffolds/list.rhtml +1 -1
- data/lib/action_controller/test_process.rb +35 -17
- data/lib/action_controller/upload_progress.rb +52 -0
- data/lib/action_controller/url_rewriter.rb +21 -16
- data/lib/action_controller/vendor/html-scanner/html/document.rb +2 -2
- data/lib/action_controller/vendor/html-scanner/html/node.rb +30 -3
- data/lib/action_pack/version.rb +9 -0
- data/lib/action_view.rb +1 -1
- data/lib/action_view/base.rb +204 -60
- data/lib/action_view/compiled_templates.rb +70 -0
- data/lib/action_view/helpers/active_record_helper.rb +7 -3
- data/lib/action_view/helpers/asset_tag_helper.rb +22 -12
- data/lib/action_view/helpers/capture_helper.rb +2 -10
- data/lib/action_view/helpers/date_helper.rb +21 -13
- data/lib/action_view/helpers/form_helper.rb +14 -10
- data/lib/action_view/helpers/form_options_helper.rb +4 -4
- data/lib/action_view/helpers/form_tag_helper.rb +59 -25
- data/lib/action_view/helpers/java_script_macros_helper.rb +188 -0
- data/lib/action_view/helpers/javascript_helper.rb +68 -133
- data/lib/action_view/helpers/javascripts/controls.js +427 -165
- data/lib/action_view/helpers/javascripts/dragdrop.js +256 -277
- data/lib/action_view/helpers/javascripts/effects.js +766 -277
- data/lib/action_view/helpers/javascripts/prototype.js +906 -218
- data/lib/action_view/helpers/javascripts/slider.js +258 -0
- data/lib/action_view/helpers/number_helper.rb +4 -3
- data/lib/action_view/helpers/pagination_helper.rb +42 -27
- data/lib/action_view/helpers/tag_helper.rb +25 -11
- data/lib/action_view/helpers/text_helper.rb +119 -13
- data/lib/action_view/helpers/upload_progress_helper.rb +2 -2
- data/lib/action_view/helpers/url_helper.rb +68 -21
- data/lib/action_view/partials.rb +17 -6
- data/lib/action_view/template_error.rb +19 -24
- data/rakefile +4 -3
- data/test/abstract_unit.rb +2 -1
- data/test/controller/action_pack_assertions_test.rb +62 -2
- data/test/controller/active_record_assertions_test.rb +5 -6
- data/test/controller/active_record_store_test.rb +23 -1
- data/test/controller/addresses_render_test.rb +4 -0
- data/test/controller/{base_tests.rb → base_test.rb} +4 -3
- data/test/controller/benchmark_test.rb +36 -0
- data/test/controller/caching_filestore.rb +22 -40
- data/test/controller/capture_test.rb +10 -1
- data/test/controller/cgi_test.rb +145 -23
- data/test/controller/components_test.rb +50 -0
- data/test/controller/custom_handler_test.rb +3 -3
- data/test/controller/fake_controllers.rb +24 -0
- data/test/controller/filters_test.rb +6 -6
- data/test/controller/flash_test.rb +6 -6
- data/test/controller/fragment_store_setting_test.rb +45 -0
- data/test/controller/helper_test.rb +1 -3
- data/test/controller/new_render_test.rb +119 -7
- data/test/controller/redirect_test.rb +11 -1
- data/test/controller/render_test.rb +34 -1
- data/test/controller/request_test.rb +14 -5
- data/test/controller/routing_test.rb +238 -42
- data/test/controller/send_file_test.rb +11 -10
- data/test/controller/session_management_test.rb +94 -0
- data/test/controller/test_test.rb +194 -5
- data/test/controller/url_rewriter_test.rb +46 -0
- data/test/fixtures/layouts/talk_from_action.rhtml +2 -0
- data/test/fixtures/layouts/yield.rhtml +2 -0
- data/test/fixtures/multipart/binary_file +0 -0
- data/test/fixtures/multipart/large_text_file +10 -0
- data/test/fixtures/multipart/mixed_files +0 -0
- data/test/fixtures/multipart/single_parameter +5 -0
- data/test/fixtures/multipart/text_file +10 -0
- data/test/fixtures/test/_customer_greeting.rhtml +1 -0
- data/test/fixtures/test/_hash_object.rhtml +1 -0
- data/test/fixtures/test/_person.rhtml +2 -0
- data/test/fixtures/test/action_talk_to_layout.rhtml +2 -0
- data/test/fixtures/test/content_for.rhtml +2 -0
- data/test/fixtures/test/potential_conflicts.rhtml +4 -0
- data/test/template/active_record_helper_test.rb +15 -8
- data/test/template/asset_tag_helper_test.rb +40 -16
- data/test/template/compiled_templates_tests.rb +63 -0
- data/test/template/date_helper_test.rb +80 -4
- data/test/template/form_helper_test.rb +48 -42
- data/test/template/form_options_helper_test.rb +40 -40
- data/test/template/form_tag_helper_test.rb +21 -15
- data/test/template/java_script_macros_helper_test.rb +56 -0
- data/test/template/javascript_helper_test.rb +70 -47
- data/test/template/number_helper_test.rb +2 -0
- data/test/template/tag_helper_test.rb +9 -0
- data/test/template/text_helper_test.rb +146 -1
- data/test/template/upload_progress_helper_testx.rb +11 -147
- data/test/template/url_helper_test.rb +90 -22
- data/test/testing_sandbox.rb +26 -0
- metadata +37 -7
- data/lib/action_controller/auto_complete.rb +0 -47
- data/lib/action_controller/deprecated_renders_and_redirects.rb +0 -76
- data/lib/action_controller/session.rb +0 -14
@@ -25,6 +25,9 @@ module ActionController #:nodoc:
|
|
25
25
|
end
|
26
26
|
class MissingFile < ActionControllerError #:nodoc:
|
27
27
|
end
|
28
|
+
class SessionOverflowError < ActionControllerError #:nodoc:
|
29
|
+
DEFAULT_MESSAGE = 'Your session data is larger than the data column in which it is to be stored. You must increase the size of your data column if you intend to store large data.'
|
30
|
+
end
|
28
31
|
class DoubleRenderError < ActionControllerError #:nodoc:
|
29
32
|
DEFAULT_MESSAGE = "Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and only once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like \"redirect_to(...) and return\". Finally, note that to cause a before filter to halt execution of the rest of the filter chain, the filter must return false, explicitly, so \"render(...) and return false\"."
|
30
33
|
|
@@ -43,7 +46,7 @@ module ActionController #:nodoc:
|
|
43
46
|
# end
|
44
47
|
#
|
45
48
|
# def sign
|
46
|
-
# Entry.create(
|
49
|
+
# Entry.create(params[:entry])
|
47
50
|
# redirect_to :action => "index"
|
48
51
|
# end
|
49
52
|
# end
|
@@ -80,7 +83,7 @@ module ActionController #:nodoc:
|
|
80
83
|
#
|
81
84
|
# def hello_ip
|
82
85
|
# location = request.env["REMOTE_IP"]
|
83
|
-
#
|
86
|
+
# render :text => "Hello stranger from #{location}"
|
84
87
|
# end
|
85
88
|
#
|
86
89
|
# == Parameters
|
@@ -117,7 +120,7 @@ module ActionController #:nodoc:
|
|
117
120
|
# 50kb object could lead to a 50MB memory overhead. In other words, think carefully about size and caching before resorting to the use
|
118
121
|
# of the session.
|
119
122
|
#
|
120
|
-
# For removing objects from the session, you can either assign a single key to nil, like <tt
|
123
|
+
# For removing objects from the session, you can either assign a single key to nil, like <tt>session[:person] = nil</tt>, or you can
|
121
124
|
# remove the entire session with reset_session.
|
122
125
|
#
|
123
126
|
# == Responses
|
@@ -196,7 +199,9 @@ module ActionController #:nodoc:
|
|
196
199
|
# def do_something
|
197
200
|
# redirect_to(:action => "elsewhere") and return if monkeys.nil?
|
198
201
|
# render :action => "overthere" # won't be called unless monkeys is nil
|
199
|
-
# end
|
202
|
+
# end
|
203
|
+
#
|
204
|
+
# == Environments
|
200
205
|
#
|
201
206
|
# Action Controller works out of the box with CGI, FastCGI, and mod_ruby. CGI and mod_ruby controllers are triggered just the same using:
|
202
207
|
#
|
@@ -206,8 +211,6 @@ module ActionController #:nodoc:
|
|
206
211
|
#
|
207
212
|
# FCGI.each_cgi{ |cgi| WeblogController.process_cgi(cgi) }
|
208
213
|
class Base
|
209
|
-
include ClassInheritableAttributes
|
210
|
-
|
211
214
|
DEFAULT_RENDER_STATUS_CODE = "200 OK"
|
212
215
|
|
213
216
|
# Determines whether the view has access to controller internals @request, @response, @session, and @template.
|
@@ -215,6 +218,10 @@ module ActionController #:nodoc:
|
|
215
218
|
@@view_controller_internals = true
|
216
219
|
cattr_accessor :view_controller_internals
|
217
220
|
|
221
|
+
# Protected instance variable cache
|
222
|
+
@@protected_variables_cache = nil
|
223
|
+
cattr_accessor :protected_variables_cache
|
224
|
+
|
218
225
|
# Prepends all the URL-generating helpers from AssetHelper. This makes it possible to easily move javascripts, stylesheets,
|
219
226
|
# and images to a dedicated asset server away from the main web server. Example:
|
220
227
|
# ActionController::Base.asset_host = "http://assets.example.com"
|
@@ -257,7 +264,7 @@ module ActionController #:nodoc:
|
|
257
264
|
# <tt>request.env["REQUEST_URI"]</tt>.
|
258
265
|
attr_accessor :request
|
259
266
|
|
260
|
-
# Holds a hash of all the GET, POST, and Url parameters passed to the action. Accessed like <tt
|
267
|
+
# Holds a hash of all the GET, POST, and Url parameters passed to the action. Accessed like <tt>params["post_id"]</tt>
|
261
268
|
# to get the post_id. No type casts are made, so all values are returned as strings.
|
262
269
|
attr_accessor :params
|
263
270
|
|
@@ -350,13 +357,14 @@ module ActionController #:nodoc:
|
|
350
357
|
initialize_template_class(response)
|
351
358
|
assign_shortcuts(request, response)
|
352
359
|
initialize_current_url
|
353
|
-
@action_name = params[
|
360
|
+
@action_name = params['action'] || 'index'
|
361
|
+
@variables_added = nil
|
354
362
|
|
355
|
-
log_processing
|
363
|
+
log_processing if logger
|
356
364
|
send(method, *arguments)
|
357
365
|
close_session
|
358
366
|
|
359
|
-
|
367
|
+
@response
|
360
368
|
end
|
361
369
|
|
362
370
|
# Returns a URL that has been rewritten according to the options hash and the defined Routes.
|
@@ -420,19 +428,14 @@ module ActionController #:nodoc:
|
|
420
428
|
#
|
421
429
|
# url_for :controller => 'posts', :action => nil
|
422
430
|
#
|
423
|
-
#
|
424
|
-
#
|
425
|
-
#
|
426
|
-
#
|
427
|
-
#
|
428
|
-
#
|
429
|
-
#
|
430
|
-
#
|
431
|
-
# protected
|
432
|
-
# def dashboard_url
|
433
|
-
# url_for :controller => (@project.active? ? "project" : "account"), :action => "dashboard"
|
434
|
-
# end
|
435
|
-
# end
|
431
|
+
# If you explicitly want to create a URL that's almost the same as the current URL, you can do so using the
|
432
|
+
# :overwrite_params options. Say for your posts you have different views for showing and printing them.
|
433
|
+
# Then, in the show view, you get the URL for the print view like this
|
434
|
+
#
|
435
|
+
# url_for :overwrite_params => { :action => 'print' }
|
436
|
+
#
|
437
|
+
# This takes the current URL as is and only exchanges the action. In contrast, <tt>url_for :action => 'print'</tt>
|
438
|
+
# would have slashed-off the path components are the changed action.
|
436
439
|
def url_for(options = {}, *parameters_for_method_reference) #:doc:
|
437
440
|
case options
|
438
441
|
when String then options
|
@@ -469,7 +472,7 @@ module ActionController #:nodoc:
|
|
469
472
|
#
|
470
473
|
# # Renders the template for the action "long_goal" within the current controller,
|
471
474
|
# # but with a custom layout
|
472
|
-
# render :action => "
|
475
|
+
# render :action => "long_goal", :layout => "spectacular"
|
473
476
|
#
|
474
477
|
# _Deprecation_ _notice_: This used to have the signatures <tt>render_action("action", status = 200)</tt>,
|
475
478
|
# <tt>render_without_layout("controller/action", status = 200)</tt>, and
|
@@ -503,19 +506,24 @@ module ActionController #:nodoc:
|
|
503
506
|
# <tt>render_partial(partial_path = default_template_name, object = nil, local_assigns = {})</tt> and
|
504
507
|
# <tt>render_partial_collection(partial_name, collection, partial_spacer_template = nil, local_assigns = {})</tt>.
|
505
508
|
#
|
506
|
-
# === Rendering a
|
509
|
+
# === Rendering a template
|
507
510
|
#
|
508
|
-
#
|
509
|
-
#
|
511
|
+
# Template rendering works just like action rendering except that it takes a path relative to the template root.
|
512
|
+
# The current layout is automatically applied.
|
510
513
|
#
|
511
514
|
# # Renders the template located in [TEMPLATE_ROOT]/weblog/show.r(html|xml) (in Rails, app/views/weblog/show.rhtml)
|
512
|
-
# render :
|
515
|
+
# render :template => "weblog/show"
|
516
|
+
#
|
517
|
+
# === Rendering a file
|
518
|
+
#
|
519
|
+
# File rendering works just like action rendering except that it takes an absolute path.
|
520
|
+
# The current layout is not applied automatically.
|
513
521
|
#
|
514
522
|
# # Renders the template located in /path/to/some/template.r(html|xml)
|
515
|
-
# render :file => "/path/to/some/template"
|
523
|
+
# render :file => "/path/to/some/template"
|
516
524
|
#
|
517
525
|
# # Renders the same template within the current layout, but with a 404 status code
|
518
|
-
# render :file => "/path/to/some/template", :
|
526
|
+
# render :file => "/path/to/some/template", :layout => true, :status => 404
|
519
527
|
#
|
520
528
|
# _Deprecation_ _notice_: This used to have the signature <tt>render_file(path, status = 200)</tt>
|
521
529
|
#
|
@@ -559,86 +567,115 @@ module ActionController #:nodoc:
|
|
559
567
|
# === Rendering nothing
|
560
568
|
#
|
561
569
|
# Rendering nothing is often convenient in combination with Ajax calls that perform their effect client-side or
|
562
|
-
# when you just want to communicate a status code.
|
570
|
+
# when you just want to communicate a status code. Due to a bug in Safari, nothing actually means a single space.
|
563
571
|
#
|
564
572
|
# # Renders an empty response with status code 200
|
565
573
|
# render :nothing => true
|
566
574
|
#
|
567
575
|
# # Renders an empty response with status code 401 (access denied)
|
568
576
|
# render :nothing => true, :status => 401
|
569
|
-
def render(options =
|
570
|
-
|
571
|
-
raise DoubleRenderError if performed?
|
577
|
+
def render(options = nil, deprecated_status = nil) #:doc:
|
578
|
+
raise DoubleRenderError, "Can only render or redirect once per action" if performed?
|
572
579
|
|
573
580
|
# Backwards compatibility
|
574
|
-
|
581
|
+
unless options.is_a?(Hash)
|
582
|
+
return render_file(options || default_template_name, deprecated_status, true)
|
583
|
+
end
|
575
584
|
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
if options[:text]
|
580
|
-
@response.headers["Status"] = options[:status]
|
581
|
-
@response.body = options[:text]
|
582
|
-
@performed_render = true
|
583
|
-
return options[:text]
|
584
|
-
|
585
|
-
elsif options[:file]
|
586
|
-
assert_existance_of_template_file(options[:file]) if options[:use_full_path]
|
587
|
-
logger.info("Rendering #{options[:file]} (#{options[:status]})") unless logger.nil?
|
588
|
-
render(options.merge({ :text => @template.render_file(options[:file], options[:use_full_path])}))
|
589
|
-
|
590
|
-
elsif options[:template]
|
591
|
-
render(options.merge({ :file => options[:template], :use_full_path => true }))
|
592
|
-
|
593
|
-
elsif options[:inline]
|
594
|
-
render(options.merge({
|
595
|
-
:text =>
|
596
|
-
@template.render_template(
|
597
|
-
options[:type] || :rhtml,
|
598
|
-
options[:inline],
|
599
|
-
options[:locals] || {}
|
600
|
-
)
|
601
|
-
}))
|
602
|
-
|
603
|
-
elsif options[:action]
|
604
|
-
render(options.merge({ :template => default_template_name(options[:action]) }))
|
605
|
-
|
606
|
-
elsif options[:partial] && options[:collection]
|
607
|
-
render(options.merge({
|
608
|
-
:text => (
|
609
|
-
@template.render_partial_collection(
|
610
|
-
options[:partial] == true ? default_template_name : options[:partial],
|
611
|
-
options[:collection], options[:spacer_template],
|
612
|
-
options[:locals] || {}
|
613
|
-
) || ''
|
614
|
-
)
|
615
|
-
}))
|
616
|
-
|
617
|
-
elsif options[:partial]
|
618
|
-
render(options.merge({ :text => @template.render_partial(
|
619
|
-
options[:partial] == true ? default_template_name : options[:partial],
|
620
|
-
options[:object], options[:locals] || {}
|
621
|
-
) }))
|
622
|
-
|
623
|
-
elsif options[:nothing]
|
624
|
-
render(options.merge({ :text => "" }))
|
585
|
+
if text = options[:text]
|
586
|
+
render_text(text, options[:status])
|
625
587
|
|
626
588
|
else
|
627
|
-
|
589
|
+
if file = options[:file]
|
590
|
+
render_file(file, options[:status], options[:use_full_path])
|
591
|
+
|
592
|
+
elsif template = options[:template]
|
593
|
+
render_file(template, options[:status], true)
|
594
|
+
|
595
|
+
elsif inline = options[:inline]
|
596
|
+
render_template(inline, options[:status], options[:type], options[:locals] || {})
|
597
|
+
|
598
|
+
elsif action_name = options[:action]
|
599
|
+
render_action(action_name, options[:status], options[:layout])
|
600
|
+
|
601
|
+
elsif partial = options[:partial]
|
602
|
+
partial = default_template_name if partial == true
|
603
|
+
if collection = options[:collection]
|
604
|
+
render_partial_collection(partial, collection, options[:spacer_template], options[:locals], options[:status])
|
605
|
+
else
|
606
|
+
render_partial(partial, ActionView::Base::ObjectWrapper.new(options[:object]), options[:locals], options[:status])
|
607
|
+
end
|
608
|
+
|
609
|
+
elsif options[:nothing]
|
610
|
+
# Safari doesn't pass the headers of the return if the response is zero length
|
611
|
+
render_text(" ", options[:status])
|
612
|
+
|
613
|
+
else
|
614
|
+
render_file(default_template_name, options[:status], true)
|
615
|
+
|
616
|
+
end
|
628
617
|
end
|
629
618
|
end
|
630
619
|
|
631
620
|
# Renders according to the same rules as <tt>render</tt>, but returns the result in a string instead
|
632
621
|
# of sending it as the response body to the browser.
|
633
|
-
def render_to_string(options =
|
622
|
+
def render_to_string(options = nil) #:doc:
|
634
623
|
result = render(options)
|
635
624
|
erase_render_results
|
636
|
-
|
625
|
+
result
|
626
|
+
end
|
627
|
+
|
628
|
+
def render_action(action_name, status = nil, with_layout = true)
|
629
|
+
if with_layout
|
630
|
+
render_with_layout(default_template_name(action_name), status)
|
631
|
+
else
|
632
|
+
render_with_no_layout(default_template_name(action_name), status)
|
633
|
+
end
|
634
|
+
end
|
635
|
+
|
636
|
+
def render_file(template_path, status = nil, use_full_path = false)
|
637
|
+
add_variables_to_assigns
|
638
|
+
assert_existance_of_template_file(template_path) if use_full_path
|
639
|
+
logger.info("Rendering #{template_path}" + (status ? " (#{status})" : '')) if logger
|
640
|
+
render_text(@template.render_file(template_path, use_full_path), status)
|
641
|
+
end
|
642
|
+
|
643
|
+
def render_template(template, status = nil, type = :rhtml, local_assigns = {})
|
644
|
+
add_variables_to_assigns
|
645
|
+
render_text(@template.render_template(type, template, nil, local_assigns), status)
|
646
|
+
end
|
647
|
+
|
648
|
+
def render_text(text = nil, status = nil)
|
649
|
+
@performed_render = true
|
650
|
+
@response.headers['Status'] = (status || DEFAULT_RENDER_STATUS_CODE).to_s
|
651
|
+
@response.body = text
|
637
652
|
end
|
638
|
-
|
653
|
+
|
654
|
+
def render_nothing(status = nil)
|
655
|
+
render_text(' ', status)
|
656
|
+
end
|
657
|
+
|
658
|
+
def render_partial(partial_path = default_template_name, object = nil, local_assigns = nil, status = nil)
|
659
|
+
add_variables_to_assigns
|
660
|
+
render_text(@template.render_partial(partial_path, object, local_assigns), status)
|
661
|
+
end
|
662
|
+
|
663
|
+
def render_partial_collection(partial_name, collection, partial_spacer_template = nil, local_assigns = nil, status = nil)
|
664
|
+
add_variables_to_assigns
|
665
|
+
render_text(@template.render_partial_collection(partial_name, collection, partial_spacer_template, local_assigns), status)
|
666
|
+
end
|
667
|
+
|
668
|
+
def render_with_layout(template_name = default_template_name, status = nil, layout = nil)
|
669
|
+
render_with_a_layout(template_name, status, layout)
|
670
|
+
end
|
671
|
+
|
672
|
+
def render_without_layout(template_name = default_template_name, status = nil)
|
673
|
+
render_with_no_layout(template_name, status)
|
674
|
+
end
|
675
|
+
|
639
676
|
|
640
677
|
# Clears the rendered results, allowing for another render to be performed.
|
641
|
-
def erase_render_results
|
678
|
+
def erase_render_results
|
642
679
|
@response.body = nil
|
643
680
|
@performed_render = false
|
644
681
|
end
|
@@ -647,7 +684,7 @@ module ActionController #:nodoc:
|
|
647
684
|
# the URL that was used to redirect or nil if there was no redirected URL
|
648
685
|
# Note that +redirect_to+ will change the body of the response to indicate a redirection.
|
649
686
|
# The response body is not reset here, see +erase_render_results+
|
650
|
-
def erase_redirect_results
|
687
|
+
def erase_redirect_results
|
651
688
|
@performed_redirect = false
|
652
689
|
response.redirected_to = nil
|
653
690
|
response.redirected_to_method_params = nil
|
@@ -655,6 +692,11 @@ module ActionController #:nodoc:
|
|
655
692
|
response.headers.delete('location')
|
656
693
|
end
|
657
694
|
|
695
|
+
# Erase both render and redirect results
|
696
|
+
def erase_results
|
697
|
+
erase_render_results
|
698
|
+
erase_redirect_results
|
699
|
+
end
|
658
700
|
|
659
701
|
def rewrite_options(options)
|
660
702
|
if defaults = default_url_options(options)
|
@@ -711,6 +753,29 @@ module ActionController #:nodoc:
|
|
711
753
|
end
|
712
754
|
end
|
713
755
|
end
|
756
|
+
|
757
|
+
# Sets a HTTP 1.1 Cache-Control header. Defaults to issuing a "private" instruction, so that
|
758
|
+
# intermediate caches shouldn't cache the response.
|
759
|
+
#
|
760
|
+
# Examples:
|
761
|
+
# expires_in 20.minutes
|
762
|
+
# expires_in 3.hours, :private => false
|
763
|
+
# expires in 3.hours, 'max-stale' => 5.hours, :private => nil, :public => true
|
764
|
+
#
|
765
|
+
# This method will overwrite an existing Cache-Control header.
|
766
|
+
# See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html for more possibilities.
|
767
|
+
def expires_in(seconds, options = {}) #:doc:
|
768
|
+
cache_options = { 'max-age' => seconds, 'private' => true }.symbolize_keys.merge!(options.symbolize_keys)
|
769
|
+
cache_options.delete_if { |k,v| v.nil? or v == false }
|
770
|
+
cache_control = cache_options.map{ |k,v| v == true ? k.to_s : "#{k.to_s}=#{v.to_s}"}
|
771
|
+
@response.headers["Cache-Control"] = cache_control.join(', ')
|
772
|
+
end
|
773
|
+
|
774
|
+
# Sets a HTTP 1.1 Cache-Control header of "no-cache" so no caching should occur by the browser or
|
775
|
+
# intermediate caches (like caching proxy servers).
|
776
|
+
def expires_now #:doc:
|
777
|
+
@response.headers["Cache-Control"] = "no-cache"
|
778
|
+
end
|
714
779
|
|
715
780
|
# Resets the session by clearing out all the objects stored within and initializing a new session object.
|
716
781
|
def reset_session #:doc:
|
@@ -720,13 +785,23 @@ module ActionController #:nodoc:
|
|
720
785
|
end
|
721
786
|
|
722
787
|
private
|
723
|
-
def
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
788
|
+
def self.view_class
|
789
|
+
unless @view_class
|
790
|
+
# create a new class based on the default template class and include helper methods
|
791
|
+
@view_class = Class.new(ActionView::Base)
|
792
|
+
@view_class.send(:include, master_helper_module)
|
728
793
|
end
|
794
|
+
@view_class
|
795
|
+
end
|
796
|
+
|
797
|
+
def self.view_root
|
798
|
+
@view_root ||= template_root
|
799
|
+
end
|
800
|
+
|
801
|
+
def initialize_template_class(response)
|
802
|
+
raise "You must assign a template class through ActionController.template_class= before processing a request" unless @@template_class
|
729
803
|
|
804
|
+
response.template = self.class.view_class.new(self.class.view_root, {}, self)
|
730
805
|
@performed_render = @performed_redirect = false
|
731
806
|
end
|
732
807
|
|
@@ -747,12 +822,12 @@ module ActionController #:nodoc:
|
|
747
822
|
end
|
748
823
|
|
749
824
|
def log_processing
|
750
|
-
logger.info "\n\nProcessing #{controller_class_name}\##{action_name} (for #{request_origin})"
|
825
|
+
logger.info "\n\nProcessing #{controller_class_name}\##{action_name} (for #{request_origin}) [#{request.method.to_s.upcase}]"
|
751
826
|
logger.info " Parameters: #{@params.inspect}"
|
752
827
|
end
|
753
828
|
|
754
829
|
def perform_action
|
755
|
-
if action_methods.include?(action_name) || action_methods.include?('method_missing')
|
830
|
+
if self.class.action_methods.include?(action_name) || self.class.action_methods.include?('method_missing')
|
756
831
|
send(action_name)
|
757
832
|
render unless performed?
|
758
833
|
elsif template_exists? && template_public?
|
@@ -767,17 +842,24 @@ module ActionController #:nodoc:
|
|
767
842
|
end
|
768
843
|
|
769
844
|
def action_methods
|
770
|
-
|
845
|
+
self.class.action_methods
|
771
846
|
end
|
772
847
|
|
848
|
+
def self.action_methods
|
849
|
+
#puts "action method: #{public_instance_methods.inspect}"
|
850
|
+
@action_methods ||= (public_instance_methods - hidden_actions).inject({}) { |h, k| h[k] = true; h }
|
851
|
+
end
|
773
852
|
|
774
853
|
def add_variables_to_assigns
|
775
|
-
|
776
|
-
|
854
|
+
unless @variables_added
|
855
|
+
add_instance_variables_to_assigns
|
856
|
+
add_class_variables_to_assigns if view_controller_internals
|
857
|
+
@variables_added = true
|
858
|
+
end
|
777
859
|
end
|
778
860
|
|
779
861
|
def add_instance_variables_to_assigns
|
780
|
-
@@protected_variables_cache
|
862
|
+
@@protected_variables_cache ||= protected_instance_variables.inject({}) { |h, k| h[k] = true; h }
|
781
863
|
instance_variables.each do |var|
|
782
864
|
next if @@protected_variables_cache.include?(var)
|
783
865
|
@assigns[var[1..-1]] = instance_variable_get(var)
|
@@ -800,7 +882,7 @@ module ActionController #:nodoc:
|
|
800
882
|
|
801
883
|
|
802
884
|
def request_origin
|
803
|
-
"#{@request.remote_ip} at #{Time.now.to_s}"
|
885
|
+
"#{@request.remote_ip} at #{Time.now.to_s(:db)}"
|
804
886
|
end
|
805
887
|
|
806
888
|
def complete_request_uri
|