actionpack 1.13.6 → 2.0.0
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 +1400 -20
- data/MIT-LICENSE +1 -1
- data/README +5 -5
- data/RUNNING_UNIT_TESTS +4 -5
- data/Rakefile +5 -6
- data/install.rb +2 -2
- data/lib/action_controller.rb +11 -15
- data/lib/action_controller/assertions.rb +12 -25
- data/lib/action_controller/assertions/dom_assertions.rb +18 -4
- data/lib/action_controller/assertions/model_assertions.rb +8 -1
- data/lib/action_controller/assertions/response_assertions.rb +35 -12
- data/lib/action_controller/assertions/routing_assertions.rb +56 -12
- data/lib/action_controller/assertions/selector_assertions.rb +105 -38
- data/lib/action_controller/assertions/tag_assertions.rb +28 -15
- data/lib/action_controller/base.rb +318 -250
- data/lib/action_controller/benchmarking.rb +33 -29
- data/lib/action_controller/caching.rb +130 -64
- data/lib/action_controller/cgi_ext.rb +16 -0
- data/lib/action_controller/cgi_ext/{cookie_performance_fix.rb → cookie.rb} +25 -40
- data/lib/action_controller/cgi_ext/query_extension.rb +22 -0
- data/lib/action_controller/cgi_ext/session.rb +73 -0
- data/lib/action_controller/cgi_ext/stdinput.rb +23 -0
- data/lib/action_controller/cgi_process.rb +34 -57
- data/lib/action_controller/components.rb +19 -36
- data/lib/action_controller/cookies.rb +10 -9
- data/lib/action_controller/dispatcher.rb +195 -0
- data/lib/action_controller/filters.rb +35 -34
- data/lib/action_controller/flash.rb +30 -35
- data/lib/action_controller/helpers.rb +121 -47
- data/lib/action_controller/http_authentication.rb +126 -0
- data/lib/action_controller/integration.rb +105 -101
- data/lib/action_controller/layout.rb +59 -47
- data/lib/action_controller/mime_responds.rb +57 -68
- data/lib/action_controller/mime_type.rb +43 -80
- data/lib/action_controller/mime_types.rb +20 -0
- data/lib/action_controller/polymorphic_routes.rb +88 -0
- data/lib/action_controller/record_identifier.rb +91 -0
- data/lib/action_controller/request.rb +553 -88
- data/lib/action_controller/request_forgery_protection.rb +126 -0
- data/lib/action_controller/request_profiler.rb +138 -0
- data/lib/action_controller/rescue.rb +185 -69
- data/lib/action_controller/resources.rb +211 -172
- data/lib/action_controller/response.rb +49 -8
- data/lib/action_controller/routing.rb +359 -236
- data/lib/action_controller/routing_optimisation.rb +119 -0
- data/lib/action_controller/session/active_record_store.rb +3 -2
- data/lib/action_controller/session/cookie_store.rb +161 -0
- data/lib/action_controller/session/mem_cache_store.rb +9 -16
- data/lib/action_controller/session_management.rb +17 -8
- data/lib/action_controller/streaming.rb +6 -3
- data/lib/action_controller/templates/rescues/_request_and_response.erb +24 -0
- data/lib/action_controller/templates/rescues/{_trace.rhtml → _trace.erb} +0 -0
- data/lib/action_controller/templates/rescues/{diagnostics.rhtml → diagnostics.erb} +2 -2
- data/lib/action_controller/templates/rescues/{layout.rhtml → layout.erb} +0 -0
- data/lib/action_controller/templates/rescues/{missing_template.rhtml → missing_template.erb} +0 -0
- data/lib/action_controller/templates/rescues/{routing_error.rhtml → routing_error.erb} +0 -0
- data/lib/action_controller/templates/rescues/{template_error.rhtml → template_error.erb} +2 -2
- data/lib/action_controller/templates/rescues/{unknown_action.rhtml → unknown_action.erb} +0 -0
- data/lib/action_controller/test_case.rb +53 -0
- data/lib/action_controller/test_process.rb +59 -46
- data/lib/action_controller/url_rewriter.rb +48 -24
- data/lib/action_controller/vendor/html-scanner/html/document.rb +7 -4
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +173 -0
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +11 -6
- data/lib/action_controller/verification.rb +27 -21
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +4 -4
- data/lib/action_view.rb +2 -3
- data/lib/action_view/base.rb +218 -63
- data/lib/action_view/compiled_templates.rb +1 -2
- data/lib/action_view/helpers/active_record_helper.rb +35 -17
- data/lib/action_view/helpers/asset_tag_helper.rb +395 -87
- data/lib/action_view/helpers/atom_feed_helper.rb +111 -0
- data/lib/action_view/helpers/benchmark_helper.rb +12 -5
- data/lib/action_view/helpers/cache_helper.rb +29 -0
- data/lib/action_view/helpers/capture_helper.rb +97 -63
- data/lib/action_view/helpers/date_helper.rb +295 -35
- data/lib/action_view/helpers/debug_helper.rb +6 -2
- data/lib/action_view/helpers/form_helper.rb +354 -111
- data/lib/action_view/helpers/form_options_helper.rb +171 -109
- data/lib/action_view/helpers/form_tag_helper.rb +332 -76
- data/lib/action_view/helpers/javascript_helper.rb +35 -11
- data/lib/action_view/helpers/javascripts/controls.js +484 -354
- data/lib/action_view/helpers/javascripts/dragdrop.js +88 -58
- data/lib/action_view/helpers/javascripts/effects.js +396 -364
- data/lib/action_view/helpers/javascripts/prototype.js +2817 -1107
- data/lib/action_view/helpers/number_helper.rb +84 -60
- data/lib/action_view/helpers/prototype_helper.rb +419 -43
- data/lib/action_view/helpers/record_identification_helper.rb +20 -0
- data/lib/action_view/helpers/record_tag_helper.rb +59 -0
- data/lib/action_view/helpers/sanitize_helper.rb +223 -0
- data/lib/action_view/helpers/scriptaculous_helper.rb +63 -4
- data/lib/action_view/helpers/tag_helper.rb +69 -39
- data/lib/action_view/helpers/text_helper.rb +221 -148
- data/lib/action_view/helpers/url_helper.rb +283 -165
- data/lib/action_view/partials.rb +134 -62
- data/lib/action_view/template_error.rb +4 -12
- data/lib/actionpack.rb +1 -0
- data/test/abstract_unit.rb +21 -1
- data/test/action_view_test.rb +26 -0
- data/test/active_record_unit.rb +12 -20
- data/test/activerecord/active_record_store_test.rb +2 -2
- data/test/activerecord/render_partial_with_record_identification_test.rb +74 -0
- data/test/controller/action_pack_assertions_test.rb +21 -152
- data/test/controller/addresses_render_test.rb +2 -7
- data/test/controller/assert_select_test.rb +120 -14
- data/test/controller/base_test.rb +11 -13
- data/test/controller/caching_test.rb +125 -5
- data/test/controller/capture_test.rb +23 -16
- data/test/controller/cgi_test.rb +66 -391
- data/test/controller/components_test.rb +31 -42
- data/test/controller/content_type_test.rb +1 -1
- data/test/controller/cookie_test.rb +42 -14
- data/test/controller/deprecation/deprecated_base_methods_test.rb +1 -42
- data/test/controller/dispatcher_test.rb +123 -0
- data/test/controller/fake_models.rb +5 -0
- data/test/controller/filters_test.rb +44 -7
- data/test/controller/flash_test.rb +46 -2
- data/test/controller/fragment_store_setting_test.rb +10 -8
- data/test/controller/helper_test.rb +19 -2
- data/test/controller/html-scanner/document_test.rb +124 -0
- data/test/controller/html-scanner/node_test.rb +69 -0
- data/test/controller/html-scanner/sanitizer_test.rb +250 -0
- data/test/controller/html-scanner/tag_node_test.rb +239 -0
- data/test/controller/html-scanner/text_node_test.rb +51 -0
- data/test/controller/html-scanner/tokenizer_test.rb +125 -0
- data/test/controller/http_authentication_test.rb +54 -0
- data/test/controller/integration_test.rb +12 -26
- data/test/controller/layout_test.rb +64 -12
- data/test/controller/mime_responds_test.rb +193 -38
- data/test/controller/mime_type_test.rb +30 -8
- data/test/controller/new_render_test.rb +104 -22
- data/test/controller/polymorphic_routes_test.rb +98 -0
- data/test/controller/record_identifier_test.rb +103 -0
- data/test/controller/redirect_test.rb +120 -18
- data/test/controller/render_test.rb +195 -45
- data/test/controller/request_forgery_protection_test.rb +217 -0
- data/test/controller/request_test.rb +545 -27
- data/test/controller/rescue_test.rb +501 -0
- data/test/controller/resources_test.rb +258 -132
- data/test/controller/routing_test.rb +502 -106
- data/test/controller/selector_test.rb +5 -5
- data/test/controller/send_file_test.rb +17 -7
- data/test/controller/session/cookie_store_test.rb +246 -0
- data/test/controller/session/mem_cache_store_test.rb +182 -0
- data/test/controller/session_fixation_test.rb +8 -11
- data/test/controller/session_management_test.rb +7 -7
- data/test/controller/test_test.rb +150 -38
- data/test/controller/url_rewriter_test.rb +87 -12
- data/test/controller/verification_test.rb +11 -0
- data/test/controller/view_paths_test.rb +137 -0
- data/test/controller/webservice_test.rb +11 -75
- data/test/fixtures/addresses/{list.rhtml → list.erb} +0 -0
- data/test/fixtures/db_definitions/sqlite.sql +2 -1
- data/test/fixtures/developer.rb +2 -0
- data/test/fixtures/fun/games/{hello_world.rhtml → hello_world.erb} +0 -0
- data/test/fixtures/helpers/fun/pdf_helper.rb +1 -1
- data/test/fixtures/layout_tests/alt/hello.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +1 -0
- data/test/fixtures/layouts/{builder.rxml → builder.builder} +0 -0
- data/test/fixtures/layouts/{standard.rhtml → standard.erb} +0 -0
- data/test/fixtures/layouts/{talk_from_action.rhtml → talk_from_action.erb} +0 -0
- data/test/fixtures/layouts/{yield.rhtml → yield.erb} +0 -0
- data/test/fixtures/multipart/binary_file +0 -0
- data/test/fixtures/multipart/bracketed_param +5 -0
- data/test/fixtures/override/test/hello_world.erb +1 -0
- data/test/fixtures/override2/layouts/test/sub.erb +1 -0
- data/test/fixtures/post_test/layouts/post.html.erb +1 -0
- data/test/fixtures/post_test/layouts/super_post.iphone.erb +1 -0
- data/test/fixtures/post_test/post/index.html.erb +1 -0
- data/test/fixtures/post_test/post/index.iphone.erb +1 -0
- data/test/fixtures/post_test/super_post/index.html.erb +1 -0
- data/test/fixtures/post_test/super_post/index.iphone.erb +1 -0
- data/test/fixtures/public/404.html +1 -0
- data/test/fixtures/public/500.html +1 -0
- data/test/fixtures/public/javascripts/application.js +0 -1
- data/test/fixtures/public/javascripts/bank.js +1 -0
- data/test/fixtures/public/javascripts/robber.js +1 -0
- data/test/fixtures/public/stylesheets/bank.css +1 -0
- data/test/fixtures/public/stylesheets/robber.css +1 -0
- data/test/fixtures/replies.yml +2 -0
- data/test/fixtures/reply.rb +2 -1
- data/test/fixtures/respond_to/{all_types_with_layout.rhtml → all_types_with_layout.html.erb} +0 -0
- data/test/fixtures/respond_to/{all_types_with_layout.rjs → all_types_with_layout.js.rjs} +0 -0
- data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +1 -0
- data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +1 -0
- data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +1 -0
- data/test/fixtures/respond_to/layouts/missing.html.erb +1 -0
- data/test/fixtures/respond_to/layouts/standard.html.erb +1 -0
- data/test/fixtures/respond_to/layouts/standard.iphone.erb +1 -0
- data/test/fixtures/respond_to/{using_defaults.rhtml → using_defaults.html.erb} +0 -0
- data/test/fixtures/respond_to/{using_defaults.rjs → using_defaults.js.rjs} +0 -0
- data/test/fixtures/respond_to/{using_defaults.rxml → using_defaults.xml.builder} +0 -0
- data/test/fixtures/respond_to/{using_defaults_with_type_list.rhtml → using_defaults_with_type_list.html.erb} +0 -0
- data/test/fixtures/respond_to/{using_defaults_with_type_list.rjs → using_defaults_with_type_list.js.rjs} +0 -0
- data/test/fixtures/respond_to/{using_defaults_with_type_list.rxml → using_defaults_with_type_list.xml.builder} +0 -0
- data/test/fixtures/scope/test/{modgreet.rhtml → modgreet.erb} +0 -0
- data/test/fixtures/test/{_customer.rhtml → _customer.erb} +0 -0
- data/test/fixtures/test/{_customer_greeting.rhtml → _customer_greeting.erb} +0 -0
- data/test/fixtures/test/_hash_greeting.erb +1 -0
- data/test/fixtures/test/_hash_object.erb +2 -0
- data/test/fixtures/test/{_hello.rxml → _hello.builder} +0 -0
- data/test/fixtures/test/_layout_for_partial.html.erb +3 -0
- data/test/fixtures/test/_partial.erb +1 -0
- data/test/fixtures/test/_partial.html.erb +1 -0
- data/test/fixtures/test/_partial.js.erb +1 -0
- data/test/fixtures/test/_partial_for_use_in_layout.html.erb +1 -0
- data/test/fixtures/test/{_partial_only.rhtml → _partial_only.erb} +0 -0
- data/test/fixtures/test/{_person.rhtml → _person.erb} +0 -0
- data/test/fixtures/test/{action_talk_to_layout.rhtml → action_talk_to_layout.erb} +0 -0
- data/test/fixtures/test/{block_content_for.rhtml → block_content_for.erb} +0 -0
- data/test/fixtures/test/calling_partial_with_layout.html.erb +1 -0
- data/test/fixtures/test/{capturing.rhtml → capturing.erb} +0 -0
- data/test/fixtures/test/{content_for.rhtml → content_for.erb} +0 -0
- data/test/fixtures/test/content_for_concatenated.erb +3 -0
- data/test/fixtures/test/content_for_with_parameter.erb +2 -0
- data/test/fixtures/test/dot.directory/{render_file_with_ivar.rhtml → render_file_with_ivar.erb} +0 -0
- data/test/fixtures/test/{erb_content_for.rhtml → erb_content_for.erb} +0 -0
- data/test/fixtures/test/formatted_html_erb.html.erb +1 -0
- data/test/fixtures/test/formatted_xml_erb.builder +1 -0
- data/test/fixtures/test/formatted_xml_erb.html.erb +1 -0
- data/test/fixtures/test/formatted_xml_erb.xml.erb +1 -0
- data/test/fixtures/test/{greeting.rhtml → greeting.erb} +0 -0
- data/test/fixtures/test/{hello.rxml → hello.builder} +0 -0
- data/test/fixtures/test/{hello_world.rxml → hello_world.builder} +0 -0
- data/test/fixtures/test/{hello_world.rhtml → hello_world.erb} +0 -0
- data/test/fixtures/test/{hello_world_container.rxml → hello_world_container.builder} +0 -0
- data/test/fixtures/test/{hello_world_with_layout_false.rhtml → hello_world_with_layout_false.erb} +0 -0
- data/test/fixtures/test/{hello_xml_world.rxml → hello_xml_world.builder} +0 -0
- data/test/fixtures/test/list.erb +1 -0
- data/test/fixtures/test/{non_erb_block_content_for.rxml → non_erb_block_content_for.builder} +0 -0
- data/test/fixtures/test/{potential_conflicts.rhtml → potential_conflicts.erb} +0 -0
- data/test/fixtures/test/{render_file_with_ivar.rhtml → render_file_with_ivar.erb} +0 -0
- data/test/fixtures/test/{render_file_with_locals.rhtml → render_file_with_locals.erb} +0 -0
- data/test/fixtures/test/{render_to_string_test.rhtml → render_to_string_test.erb} +0 -0
- data/test/fixtures/test/{update_element_with_capture.rhtml → update_element_with_capture.erb} +0 -0
- data/test/fixtures/test/using_layout_around_block.html.erb +1 -0
- data/test/fixtures/topic.rb +1 -1
- data/test/template/active_record_helper_test.rb +67 -20
- data/test/template/asset_tag_helper_test.rb +222 -54
- data/test/template/atom_feed_helper_test.rb +101 -0
- data/test/template/benchmark_helper_test.rb +2 -2
- data/test/template/compiled_templates_test.rb +76 -32
- data/test/template/date_helper_test.rb +125 -9
- data/test/template/form_helper_test.rb +326 -33
- data/test/template/form_options_helper_test.rb +822 -15
- data/test/template/form_tag_helper_test.rb +96 -30
- data/test/template/javascript_helper_test.rb +61 -13
- data/test/template/number_helper_test.rb +12 -11
- data/test/template/prototype_helper_test.rb +185 -24
- data/test/template/sanitize_helper_test.rb +49 -0
- data/test/template/scriptaculous_helper_test.rb +9 -3
- data/test/template/tag_helper_test.rb +13 -2
- data/test/template/text_helper_test.rb +38 -52
- data/test/template/url_helper_test.rb +216 -46
- metadata +144 -116
- data/examples/.htaccess +0 -24
- data/examples/address_book/index.rhtml +0 -33
- data/examples/address_book/layout.rhtml +0 -8
- data/examples/address_book_controller.cgi +0 -9
- data/examples/address_book_controller.fcgi +0 -6
- data/examples/address_book_controller.rb +0 -52
- data/examples/address_book_controller.rbx +0 -4
- data/examples/benchmark.rb +0 -52
- data/examples/benchmark_with_ar.fcgi +0 -89
- data/examples/blog_controller.cgi +0 -53
- data/examples/debate/index.rhtml +0 -14
- data/examples/debate/new_topic.rhtml +0 -22
- data/examples/debate/topic.rhtml +0 -32
- data/examples/debate_controller.cgi +0 -57
- data/lib/action_controller/assertions/deprecated_assertions.rb +0 -228
- data/lib/action_controller/cgi_ext/cgi_ext.rb +0 -36
- data/lib/action_controller/cgi_ext/cgi_methods.rb +0 -211
- data/lib/action_controller/cgi_ext/pstore_performance_fix.rb +0 -30
- data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +0 -95
- data/lib/action_controller/cgi_ext/session_performance_fix.rb +0 -30
- data/lib/action_controller/deprecated_dependencies.rb +0 -65
- data/lib/action_controller/deprecated_redirects.rb +0 -17
- data/lib/action_controller/deprecated_request_methods.rb +0 -34
- data/lib/action_controller/macros/auto_complete.rb +0 -53
- data/lib/action_controller/macros/in_place_editing.rb +0 -33
- data/lib/action_controller/pagination.rb +0 -408
- data/lib/action_controller/scaffolding.rb +0 -189
- data/lib/action_controller/templates/rescues/_request_and_response.rhtml +0 -44
- data/lib/action_controller/templates/scaffolds/edit.rhtml +0 -7
- data/lib/action_controller/templates/scaffolds/layout.rhtml +0 -69
- data/lib/action_controller/templates/scaffolds/list.rhtml +0 -27
- data/lib/action_controller/templates/scaffolds/new.rhtml +0 -6
- data/lib/action_controller/templates/scaffolds/show.rhtml +0 -9
- data/lib/action_controller/vendor/xml_node.rb +0 -97
- data/lib/action_view/helpers/deprecated_helper.rb +0 -37
- data/lib/action_view/helpers/java_script_macros_helper.rb +0 -233
- data/lib/action_view/helpers/pagination_helper.rb +0 -86
- data/test/activerecord/active_record_assertions_test.rb +0 -92
- data/test/activerecord/pagination_test.rb +0 -165
- data/test/controller/deprecated_instance_variables_test.rb +0 -48
- data/test/controller/raw_post_test.rb +0 -68
- data/test/fixtures/deprecated_instance_variables/_cookies_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_cookies_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_flash_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_flash_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_headers_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_headers_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_params_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_params_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_request_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_request_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_response_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_response_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_session_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_session_method.rhtml +0 -1
- data/test/fixtures/respond_to/layouts/standard.rhtml +0 -1
- data/test/fixtures/test/_hash_object.rhtml +0 -1
- data/test/fixtures/test/list.rhtml +0 -1
- data/test/template/deprecated_helper_test.rb +0 -36
- data/test/template/deprecated_instance_variables_test.rb +0 -43
- data/test/template/java_script_macros_helper_test.rb +0 -109
data/lib/action_view/partials.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
module ActionView
|
2
|
-
# There's also a convenience method for rendering sub templates within the current controller that depends on a single object
|
3
|
-
# (we call this kind of sub templates for partials). It relies on the fact that partials should follow the naming convention of being
|
4
|
-
# prefixed with an underscore -- as to separate them from regular templates that could be rendered on their own.
|
2
|
+
# There's also a convenience method for rendering sub templates within the current controller that depends on a single object
|
3
|
+
# (we call this kind of sub templates for partials). It relies on the fact that partials should follow the naming convention of being
|
4
|
+
# prefixed with an underscore -- as to separate them from regular templates that could be rendered on their own.
|
5
5
|
#
|
6
6
|
# In a template for Advertiser#account:
|
7
7
|
#
|
8
8
|
# <%= render :partial => "account" %>
|
9
9
|
#
|
10
|
-
# This would render "advertiser/_account.
|
10
|
+
# This would render "advertiser/_account.erb" and pass the instance variable @account in as a local variable +account+ to
|
11
11
|
# the template for display.
|
12
12
|
#
|
13
13
|
# In another template for Advertiser#buy, we could have:
|
@@ -18,8 +18,8 @@ module ActionView
|
|
18
18
|
# <%= render :partial => "ad", :locals => { :ad => ad } %>
|
19
19
|
# <% end %>
|
20
20
|
#
|
21
|
-
# This would first render "advertiser/_account.
|
22
|
-
# "advertiser/_ad.
|
21
|
+
# This would first render "advertiser/_account.erb" with @buyer passed in as the local variable +account+, then render
|
22
|
+
# "advertiser/_ad.erb" and pass the local variable +ad+ to the template for display.
|
23
23
|
#
|
24
24
|
# == Rendering a collection of partials
|
25
25
|
#
|
@@ -30,62 +30,131 @@ module ActionView
|
|
30
30
|
#
|
31
31
|
# <%= render :partial => "ad", :collection => @advertisements %>
|
32
32
|
#
|
33
|
-
# This will render "advertiser/_ad.
|
34
|
-
# will automatically be made available to the template with a name of the form +partial_name_counter+. In the case of the
|
33
|
+
# This will render "advertiser/_ad.erb" and pass the local variable +ad+ to the template for display. An iteration counter
|
34
|
+
# will automatically be made available to the template with a name of the form +partial_name_counter+. In the case of the
|
35
35
|
# example above, the template would be fed +ad_counter+.
|
36
36
|
#
|
37
37
|
# NOTE: Due to backwards compatibility concerns, the collection can't be one of hashes. Normally you'd also just keep domain objects,
|
38
38
|
# like Active Records, in there.
|
39
|
-
#
|
39
|
+
#
|
40
40
|
# == Rendering shared partials
|
41
41
|
#
|
42
42
|
# Two controllers can share a set of partials and render them like this:
|
43
43
|
#
|
44
44
|
# <%= render :partial => "advertisement/ad", :locals => { :ad => @advertisement } %>
|
45
45
|
#
|
46
|
-
# This will render the partial "advertisement/_ad.
|
46
|
+
# This will render the partial "advertisement/_ad.erb" regardless of which controller this is being called from.
|
47
|
+
#
|
48
|
+
# == Rendering partials with layouts
|
49
|
+
#
|
50
|
+
# Partials can have their own layouts applied to them. These layouts are different than the ones that are specified globally
|
51
|
+
# for the entire action, but they work in a similar fashion. Imagine a list with two types of users:
|
52
|
+
#
|
53
|
+
# <%# app/views/users/index.html.erb &>
|
54
|
+
# Here's the administrator:
|
55
|
+
# <%= render :partial => "user", :layout => "administrator", :locals => { :user => administrator } %>
|
56
|
+
#
|
57
|
+
# Here's the editor:
|
58
|
+
# <%= render :partial => "user", :layout => "editor", :locals => { :user => editor } %>
|
59
|
+
#
|
60
|
+
# <%# app/views/users/_user.html.erb &>
|
61
|
+
# Name: <%= user.name %>
|
62
|
+
#
|
63
|
+
# <%# app/views/users/_administrator.html.erb &>
|
64
|
+
# <div id="administrator">
|
65
|
+
# Budget: $<%= user.budget %>
|
66
|
+
# <%= yield %>
|
67
|
+
# </div>
|
68
|
+
#
|
69
|
+
# <%# app/views/users/_editor.html.erb &>
|
70
|
+
# <div id="editor">
|
71
|
+
# Deadline: $<%= user.deadline %>
|
72
|
+
# <%= yield %>
|
73
|
+
# </div>
|
74
|
+
#
|
75
|
+
# ...this will return:
|
76
|
+
#
|
77
|
+
# Here's the administrator:
|
78
|
+
# <div id="administrator">
|
79
|
+
# Budget: $<%= user.budget %>
|
80
|
+
# Name: <%= user.name %>
|
81
|
+
# </div>
|
82
|
+
#
|
83
|
+
# Here's the editor:
|
84
|
+
# <div id="editor">
|
85
|
+
# Deadline: $<%= user.deadline %>
|
86
|
+
# Name: <%= user.name %>
|
87
|
+
# </div>
|
88
|
+
#
|
89
|
+
# You can also apply a layout to a block within any template:
|
90
|
+
#
|
91
|
+
# <%# app/views/users/_chief.html.erb &>
|
92
|
+
# <% render(:layout => "administrator", :locals => { :user => chief }) do %>
|
93
|
+
# Title: <%= chief.title %>
|
94
|
+
# <% end %>
|
95
|
+
#
|
96
|
+
# ...this will return:
|
97
|
+
#
|
98
|
+
# <div id="administrator">
|
99
|
+
# Budget: $<%= user.budget %>
|
100
|
+
# Title: <%= chief.name %>
|
101
|
+
# </div>
|
102
|
+
#
|
103
|
+
# As you can see, the :locals hash is shared between both the partial and its layout.
|
47
104
|
module Partials
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
105
|
+
private
|
106
|
+
def render_partial(partial_path, object_assigns = nil, local_assigns = nil) #:nodoc:
|
107
|
+
case partial_path
|
108
|
+
when String, Symbol, NilClass
|
109
|
+
path, partial_name = partial_pieces(partial_path)
|
110
|
+
object = extracting_object(partial_name, object_assigns)
|
111
|
+
local_assigns = local_assigns ? local_assigns.clone : {}
|
112
|
+
add_counter_to_local_assigns!(partial_name, local_assigns)
|
113
|
+
add_object_to_local_assigns!(partial_name, local_assigns, object)
|
56
114
|
|
57
|
-
|
58
|
-
|
59
|
-
|
115
|
+
if logger && logger.debug?
|
116
|
+
ActionController::Base.benchmark("Rendered #{path}/_#{partial_name}", Logger::DEBUG, false) do
|
117
|
+
render("#{path}/_#{partial_name}", local_assigns)
|
118
|
+
end
|
119
|
+
else
|
120
|
+
render("#{path}/_#{partial_name}", local_assigns)
|
121
|
+
end
|
122
|
+
when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::Associations::HasManyThroughAssociation
|
123
|
+
if partial_path.any?
|
124
|
+
path = ActionController::RecordIdentifier.partial_path(partial_path.first)
|
125
|
+
collection = partial_path
|
126
|
+
render_partial_collection(path, collection, nil, object_assigns.value)
|
127
|
+
else
|
128
|
+
""
|
129
|
+
end
|
130
|
+
else
|
131
|
+
render_partial(
|
132
|
+
ActionController::RecordIdentifier.partial_path(partial_path),
|
133
|
+
object_assigns, local_assigns)
|
60
134
|
end
|
61
|
-
else
|
62
|
-
render("#{path}/_#{partial_name}", local_assigns)
|
63
135
|
end
|
64
|
-
end
|
65
136
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
end
|
137
|
+
def render_partial_collection(partial_name, collection, partial_spacer_template = nil, local_assigns = nil) #:nodoc:
|
138
|
+
collection_of_partials = Array.new
|
139
|
+
counter_name = partial_counter_name(partial_name)
|
140
|
+
local_assigns = local_assigns ? local_assigns.clone : {}
|
141
|
+
collection.each_with_index do |element, counter|
|
142
|
+
local_assigns[counter_name] = counter
|
143
|
+
collection_of_partials.push(render_partial(partial_name, element, local_assigns))
|
144
|
+
end
|
75
145
|
|
76
|
-
|
146
|
+
return " " if collection_of_partials.empty?
|
77
147
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
148
|
+
if partial_spacer_template
|
149
|
+
spacer_path, spacer_name = partial_pieces(partial_spacer_template)
|
150
|
+
collection_of_partials.join(render("#{spacer_path}/_#{spacer_name}"))
|
151
|
+
else
|
152
|
+
collection_of_partials.join
|
153
|
+
end
|
83
154
|
end
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
private
|
155
|
+
|
156
|
+
alias_method :render_collection_of_partials, :render_partial_collection
|
157
|
+
|
89
158
|
def partial_pieces(partial_path)
|
90
159
|
if partial_path.include?('/')
|
91
160
|
return File.dirname(partial_path), File.basename(partial_path)
|
@@ -95,34 +164,37 @@ module ActionView
|
|
95
164
|
end
|
96
165
|
|
97
166
|
def partial_counter_name(partial_name)
|
98
|
-
"#{partial_name
|
167
|
+
"#{partial_variable_name(partial_name)}_counter".intern
|
99
168
|
end
|
100
|
-
|
101
|
-
def
|
102
|
-
|
103
|
-
|
169
|
+
|
170
|
+
def partial_variable_name(partial_name)
|
171
|
+
partial_name.split('/').last.split('.').first.intern
|
172
|
+
end
|
173
|
+
|
174
|
+
def extracting_object(partial_name, object_assigns)
|
175
|
+
variable_name = partial_variable_name(partial_name)
|
176
|
+
if object_assigns.nil?
|
177
|
+
controller.instance_variable_get("@#{variable_name}")
|
104
178
|
else
|
105
|
-
|
106
|
-
local_assigns
|
179
|
+
object_assigns
|
107
180
|
end
|
108
181
|
end
|
109
|
-
|
110
|
-
def extract_local_assigns(local_assigns, deprecated_local_assigns)
|
111
|
-
local_assigns.is_a?(Hash) ? local_assigns : deprecated_local_assigns
|
112
|
-
end
|
113
|
-
|
182
|
+
|
114
183
|
def add_counter_to_local_assigns!(partial_name, local_assigns)
|
115
184
|
counter_name = partial_counter_name(partial_name)
|
116
185
|
local_assigns[counter_name] = 1 unless local_assigns.has_key?(counter_name)
|
117
186
|
end
|
118
187
|
|
119
188
|
def add_object_to_local_assigns!(partial_name, local_assigns, object)
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
object
|
125
|
-
|
189
|
+
variable_name = partial_variable_name(partial_name)
|
190
|
+
|
191
|
+
local_assigns[:object] ||=
|
192
|
+
local_assigns[variable_name] ||=
|
193
|
+
if object.is_a?(ActionView::Base::ObjectWrapper)
|
194
|
+
object.value
|
195
|
+
else
|
196
|
+
object
|
197
|
+
end || controller.instance_variable_get("@#{variable_name}")
|
126
198
|
end
|
127
199
|
end
|
128
200
|
end
|
@@ -10,8 +10,6 @@ module ActionView
|
|
10
10
|
@base_path, @assigns, @source, @original_exception =
|
11
11
|
base_path, assigns.dup, source, original_exception
|
12
12
|
@file_path = file_path
|
13
|
-
|
14
|
-
remove_deprecated_assigns!
|
15
13
|
end
|
16
14
|
|
17
15
|
def message
|
@@ -82,16 +80,10 @@ module ActionView
|
|
82
80
|
end
|
83
81
|
|
84
82
|
private
|
85
|
-
def remove_deprecated_assigns!
|
86
|
-
ActionController::Base::DEPRECATED_INSTANCE_VARIABLES.each do |ivar|
|
87
|
-
@assigns.delete(ivar)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
83
|
def strip_base_path(path)
|
92
|
-
File.expand_path(path).
|
93
|
-
|
94
|
-
|
84
|
+
stripped_path = File.expand_path(path).gsub(@base_path, "")
|
85
|
+
stripped_path.gsub!(/^#{Regexp.escape File.expand_path(RAILS_ROOT)}/, '') if defined?(RAILS_ROOT)
|
86
|
+
stripped_path
|
95
87
|
end
|
96
88
|
|
97
89
|
def source_location
|
@@ -106,5 +98,5 @@ end
|
|
106
98
|
|
107
99
|
if defined?(Exception::TraceSubstitutions)
|
108
100
|
Exception::TraceSubstitutions << [/:in\s+`_run_(html|xml).*'\s*$/, '']
|
109
|
-
Exception::TraceSubstitutions << [%r{^\s*#{Regexp.escape RAILS_ROOT}}, '
|
101
|
+
Exception::TraceSubstitutions << [%r{^\s*#{Regexp.escape RAILS_ROOT}/}, ''] if defined?(RAILS_ROOT)
|
110
102
|
end
|
data/lib/actionpack.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'action_pack'
|
data/test/abstract_unit.rb
CHANGED
@@ -3,14 +3,34 @@ $:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib/active_support')
|
|
3
3
|
$:.unshift(File.dirname(__FILE__) + '/fixtures/helpers')
|
4
4
|
|
5
5
|
require 'yaml'
|
6
|
+
require 'stringio'
|
6
7
|
require 'test/unit'
|
7
8
|
require 'action_controller'
|
8
|
-
require '
|
9
|
+
require 'action_controller/cgi_ext'
|
9
10
|
require 'action_controller/test_process'
|
10
11
|
|
12
|
+
begin
|
13
|
+
require 'ruby-debug'
|
14
|
+
rescue LoadError
|
15
|
+
# Debugging disabled. `gem install ruby-debug` to enable.
|
16
|
+
end
|
17
|
+
|
11
18
|
# Show backtraces for deprecated behavior for quicker cleanup.
|
12
19
|
ActiveSupport::Deprecation.debug = true
|
13
20
|
|
14
21
|
ActionController::Base.logger = nil
|
15
22
|
ActionController::Base.ignore_missing_templates = false
|
16
23
|
ActionController::Routing::Routes.reload rescue nil
|
24
|
+
|
25
|
+
|
26
|
+
# Wrap tests that use Mocha and skip if unavailable.
|
27
|
+
def uses_mocha(test_name)
|
28
|
+
unless Object.const_defined?(:Mocha)
|
29
|
+
require 'mocha'
|
30
|
+
require 'stubba'
|
31
|
+
end
|
32
|
+
yield
|
33
|
+
rescue LoadError => load_error
|
34
|
+
raise unless load_error.message =~ /mocha/i
|
35
|
+
$stderr.puts "Skipping #{test_name} tests. `gem install mocha` and try again."
|
36
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/abstract_unit'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
class ActionViewTests < Test::Unit::TestCase
|
5
|
+
def test_find_template_extension_from_first_render
|
6
|
+
base = ActionView::Base.new
|
7
|
+
|
8
|
+
assert_nil base.send(:find_template_extension_from_first_render)
|
9
|
+
|
10
|
+
{
|
11
|
+
nil => nil,
|
12
|
+
'' => nil,
|
13
|
+
'foo' => nil,
|
14
|
+
'/foo' => nil,
|
15
|
+
'foo.rb' => 'rb',
|
16
|
+
'foo.bar.rb' => 'bar.rb',
|
17
|
+
'baz/foo.rb' => 'rb',
|
18
|
+
'baz/foo.bar.rb' => 'bar.rb',
|
19
|
+
'baz/foo.o/foo.rb' => 'rb',
|
20
|
+
'baz/foo.o/foo.bar.rb' => 'bar.rb',
|
21
|
+
}.each do |input,expectation|
|
22
|
+
base.instance_variable_set('@first_render', input)
|
23
|
+
assert_equal expectation, base.send(:find_template_extension_from_first_render)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/test/active_record_unit.rb
CHANGED
@@ -51,22 +51,23 @@ class ActiveRecordTestConnector
|
|
51
51
|
|
52
52
|
def setup_connection
|
53
53
|
if Object.const_defined?(:ActiveRecord)
|
54
|
+
defaults = { :database => ':memory:' }
|
54
55
|
begin
|
55
|
-
|
56
|
-
ActiveRecord::Base.establish_connection(
|
57
|
-
ActiveRecord::Base.configurations = { 'sqlite3_ar_integration' =>
|
56
|
+
options = defaults.merge :adapter => 'sqlite3', :timeout => 500
|
57
|
+
ActiveRecord::Base.establish_connection(options)
|
58
|
+
ActiveRecord::Base.configurations = { 'sqlite3_ar_integration' => options }
|
58
59
|
ActiveRecord::Base.connection
|
59
60
|
rescue Exception # errors from establishing a connection
|
60
|
-
$stderr.puts 'SQLite 3 unavailable;
|
61
|
-
|
62
|
-
ActiveRecord::Base.establish_connection(
|
63
|
-
ActiveRecord::Base.configurations = { 'sqlite2_ar_integration' =>
|
61
|
+
$stderr.puts 'SQLite 3 unavailable; trying SQLite 2.'
|
62
|
+
options = defaults.merge :adapter => 'sqlite'
|
63
|
+
ActiveRecord::Base.establish_connection(options)
|
64
|
+
ActiveRecord::Base.configurations = { 'sqlite2_ar_integration' => options }
|
64
65
|
ActiveRecord::Base.connection
|
65
66
|
end
|
66
67
|
|
67
68
|
Object.send(:const_set, :QUOTED_TYPE, ActiveRecord::Base.connection.quote_column_name('type')) unless Object.const_defined?(:QUOTED_TYPE)
|
68
69
|
else
|
69
|
-
raise "
|
70
|
+
raise "Can't setup connection since ActiveRecord isn't loaded."
|
70
71
|
end
|
71
72
|
end
|
72
73
|
|
@@ -83,7 +84,7 @@ class ActiveRecordTestConnector
|
|
83
84
|
end
|
84
85
|
end
|
85
86
|
|
86
|
-
# Test case for
|
87
|
+
# Test case for inheritance
|
87
88
|
class ActiveRecordTestCase < Test::Unit::TestCase
|
88
89
|
# Set our fixture path
|
89
90
|
if ActiveRecordTestConnector.able_to_connect
|
@@ -95,22 +96,13 @@ class ActiveRecordTestCase < Test::Unit::TestCase
|
|
95
96
|
super if ActiveRecordTestConnector.connected
|
96
97
|
end
|
97
98
|
|
98
|
-
def
|
99
|
-
|
99
|
+
def run(*args)
|
100
|
+
super if ActiveRecordTestConnector.connected
|
100
101
|
end
|
101
102
|
|
102
103
|
# Default so Test::Unit::TestCase doesn't complain
|
103
104
|
def test_truth
|
104
105
|
end
|
105
|
-
|
106
|
-
private
|
107
|
-
# If things go wrong, we don't want to run our test cases. We'll just define them to test nothing.
|
108
|
-
def abort_tests
|
109
|
-
$stderr.puts 'No Active Record connection, aborting tests.'
|
110
|
-
self.class.public_instance_methods.grep(/^test./).each do |method|
|
111
|
-
self.class.class_eval { define_method(method.to_sym){} }
|
112
|
-
end
|
113
|
-
end
|
114
106
|
end
|
115
107
|
|
116
108
|
ActiveRecordTestConnector.setup
|
@@ -53,7 +53,7 @@ class ActiveRecordStoreTest < ActiveRecordTestCase
|
|
53
53
|
@new_session['foo'] = 'bar'
|
54
54
|
end
|
55
55
|
|
56
|
-
# this test only applies for eager
|
56
|
+
# this test only applies for eager session saving
|
57
57
|
# def test_another_instance
|
58
58
|
# @another = CGI::Session.new(@cgi, 'session_id' => @new_session.session_id, 'database_manager' => CGI::Session::ActiveRecordStore)
|
59
59
|
# assert_equal @new_session.session_id, @another.session_id
|
@@ -128,7 +128,7 @@ end
|
|
128
128
|
|
129
129
|
class SqlBypassActiveRecordStoreTest < ActiveRecordStoreTest
|
130
130
|
def session_class
|
131
|
-
unless @session_class
|
131
|
+
unless defined? @session_class
|
132
132
|
@session_class = CGI::Session::ActiveRecordStore::SqlBypass
|
133
133
|
@session_class.connection = CGI::Session::ActiveRecordStore::Session.connection
|
134
134
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../active_record_unit'
|
2
|
+
|
3
|
+
class RenderPartialWithRecordIdentificationTest < ActiveRecordTestCase
|
4
|
+
fixtures :developers, :projects, :developers_projects, :topics, :replies
|
5
|
+
|
6
|
+
class RenderPartialWithRecordIdentificationController < ActionController::Base
|
7
|
+
def render_with_has_many_and_belongs_to_association
|
8
|
+
@developer = Developer.find(1)
|
9
|
+
render :partial => @developer.projects
|
10
|
+
end
|
11
|
+
|
12
|
+
def render_with_has_many_association
|
13
|
+
@topic = Topic.find(1)
|
14
|
+
render :partial => @topic.replies
|
15
|
+
end
|
16
|
+
|
17
|
+
def render_with_has_many_through_association
|
18
|
+
@developer = Developer.find(:first)
|
19
|
+
render :partial => @developer.topics
|
20
|
+
end
|
21
|
+
|
22
|
+
def render_with_belongs_to_association
|
23
|
+
@reply = Reply.find(1)
|
24
|
+
render :partial => @reply.topic
|
25
|
+
end
|
26
|
+
|
27
|
+
def render_with_record
|
28
|
+
@developer = Developer.find(:first)
|
29
|
+
render :partial => @developer
|
30
|
+
end
|
31
|
+
|
32
|
+
def render_with_record_collection
|
33
|
+
@developers = Developer.find(:all)
|
34
|
+
render :partial => @developers
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def setup
|
39
|
+
@controller = RenderPartialWithRecordIdentificationController.new
|
40
|
+
@request = ActionController::TestRequest.new
|
41
|
+
@response = ActionController::TestResponse.new
|
42
|
+
super
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_rendering_partial_with_has_many_and_belongs_to_association
|
46
|
+
get :render_with_has_many_and_belongs_to_association
|
47
|
+
assert_template 'projects/_project'
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_rendering_partial_with_has_many_association
|
51
|
+
get :render_with_has_many_association
|
52
|
+
assert_template 'replies/_reply'
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_rendering_partial_with_has_many_association
|
56
|
+
get :render_with_has_many_through_association
|
57
|
+
assert_template 'topics/_topic'
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_rendering_partial_with_belongs_to_association
|
61
|
+
get :render_with_belongs_to_association
|
62
|
+
assert_template 'topics/_topic'
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_render_with_record
|
66
|
+
get :render_with_record
|
67
|
+
assert_template 'developers/_developer'
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_render_with_record_collection
|
71
|
+
get :render_with_record_collection
|
72
|
+
assert_template 'developers/_developer'
|
73
|
+
end
|
74
|
+
end
|