Permalink
Browse files

Merge commit 'mainstream/master'

Conflicts:
	actionpack/lib/action_view/helpers/form_helper.rb
  • Loading branch information...
2 parents 26ad104 + eb02170 commit 59653101b8cef7915cb1fb4ad4b84f49ae0881e5 @lifo lifo committed May 15, 2009
Showing with 10,330 additions and 2,806 deletions.
  1. +2 −2 Rakefile
  2. +6 −0 actionmailer/Rakefile
  3. +1 −0 actionmailer/lib/action_mailer/vendor/tmail.rb
  4. +17 −3 actionpack/Rakefile
  5. +34 −0 actionpack/examples/minimal.rb
  6. +4 −11 actionpack/lib/action_controller.rb
  7. +3 −0 actionpack/lib/action_controller/abstract.rb
  8. +80 −9 actionpack/lib/action_controller/abstract/base.rb
  9. +9 −6 actionpack/lib/action_controller/abstract/callbacks.rb
  10. +5 −10 actionpack/lib/action_controller/abstract/helpers.rb
  11. +9 −5 actionpack/lib/action_controller/abstract/layouts.rb
  12. +39 −2 actionpack/lib/action_controller/abstract/logger.rb
  13. +24 −11 actionpack/lib/action_controller/abstract/renderer.rb
  14. +25 −22 actionpack/lib/action_controller/base/base.rb
  15. +1 −1 actionpack/lib/action_controller/base/chained/benchmarking.rb
  16. +4 −2 actionpack/lib/action_controller/base/http_authentication.rb
  17. +4 −0 actionpack/lib/action_controller/base/layout.rb
  18. +3 −5 actionpack/lib/action_controller/base/redirect.rb
  19. +2 −1 actionpack/lib/action_controller/base/render.rb
  20. +50 −0 actionpack/lib/action_controller/base/rescue.rb
  21. +9 −1 actionpack/lib/action_controller/caching/actions.rb
  22. +23 −32 actionpack/lib/action_controller/dispatch/dispatcher.rb
  23. +6 −1 actionpack/lib/action_controller/dispatch/middlewares.rb
  24. +0 −185 actionpack/lib/action_controller/dispatch/rescue.rb
  25. +0 −10 actionpack/lib/action_controller/dispatch/templates/rescues/diagnostics.erb
  26. +27 −6 actionpack/lib/action_controller/new_base.rb
  27. +112 −45 actionpack/lib/action_controller/new_base/base.rb
  28. +91 −0 actionpack/lib/action_controller/new_base/compatibility.rb
  29. +131 −0 actionpack/lib/action_controller/new_base/conditional_get.rb
  30. +7 −5 actionpack/lib/action_controller/new_base/hide_actions.rb
  31. +68 −0 actionpack/lib/action_controller/new_base/http.rb
  32. +3 −1 actionpack/lib/action_controller/new_base/layouts.rb
  33. +19 −0 actionpack/lib/action_controller/new_base/redirector.rb
  34. +36 −22 actionpack/lib/action_controller/new_base/renderer.rb
  35. +25 −0 actionpack/lib/action_controller/new_base/testing.rb
  36. +2 −0 actionpack/lib/action_controller/record_identifier.rb
  37. +4 −0 actionpack/lib/action_controller/routing.rb
  38. +2 −0 actionpack/lib/action_controller/routing/builder.rb
  39. +5 −3 actionpack/lib/action_controller/routing/route.rb
  40. +1 −1 actionpack/lib/action_controller/routing/route_set.rb
  41. +0 −162 actionpack/lib/action_controller/testing/assertions/response.rb
  42. +134 −212 actionpack/lib/action_controller/testing/integration.rb
  43. +54 −206 actionpack/lib/action_controller/testing/process.rb
  44. +70 −0 actionpack/lib/action_controller/testing/process2.rb
  45. +1 −14 actionpack/lib/action_controller/testing/test_case.rb
  46. +13 −15 actionpack/lib/action_dispatch.rb
  47. +1 −0 actionpack/lib/action_dispatch/http/mime_type.rb
  48. +24 −19 actionpack/lib/action_dispatch/http/request.rb
  49. +3 −57 actionpack/lib/action_dispatch/http/response.rb
  50. +4 −2 actionpack/lib/action_dispatch/http/status_codes.rb
  51. +1 −1 actionpack/lib/action_dispatch/middleware/params_parser.rb
  52. +0 −14 actionpack/lib/action_dispatch/middleware/reloader.rb
  53. +14 −0 actionpack/lib/action_dispatch/middleware/rescue.rb
  54. +144 −0 actionpack/lib/action_dispatch/middleware/show_exceptions.rb
  55. +1 −4 actionpack/lib/action_dispatch/middleware/stack.rb
  56. +3 −3 ...ion_controller/dispatch → action_dispatch/middleware}/templates/rescues/_request_and_response.erb
  57. 0 ...onpack/lib/{action_controller/dispatch → action_dispatch/middleware}/templates/rescues/_trace.erb
  58. +10 −0 actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb
  59. +2 −2 ...onpack/lib/{action_controller/dispatch → action_dispatch/middleware}/templates/rescues/layout.erb
  60. 0 .../{action_controller/dispatch → action_dispatch/middleware}/templates/rescues/missing_template.erb
  61. 0 ...lib/{action_controller/dispatch → action_dispatch/middleware}/templates/rescues/routing_error.erb
  62. +3 −3 ...ib/{action_controller/dispatch → action_dispatch/middleware}/templates/rescues/template_error.erb
  63. 0 ...ib/{action_controller/dispatch → action_dispatch/middleware}/templates/rescues/unknown_action.erb
  64. +0 −115 actionpack/lib/action_dispatch/test/mock.rb
  65. +0 −33 actionpack/lib/action_dispatch/test/uploaded_file.rb
  66. +8 −0 actionpack/lib/action_dispatch/testing/assertions.rb
  67. +9 −13 actionpack/lib/{action_controller → action_dispatch}/testing/assertions/dom.rb
  68. +2 −4 actionpack/lib/{action_controller → action_dispatch}/testing/assertions/model.rb
  69. +145 −0 actionpack/lib/action_dispatch/testing/assertions/response.rb
  70. +20 −24 actionpack/lib/{action_controller → action_dispatch}/testing/assertions/routing.rb
  71. +1 −1 actionpack/lib/{action_controller → action_dispatch}/testing/assertions/selector.rb
  72. +7 −11 actionpack/lib/{action_controller → action_dispatch}/testing/assertions/tag.rb
  73. +83 −0 actionpack/lib/action_dispatch/testing/test_request.rb
  74. +131 −0 actionpack/lib/action_dispatch/testing/test_response.rb
  75. +90 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack.rb
  76. +22 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/adapter/camping.rb
  77. +37 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/auth/abstract/handler.rb
  78. +37 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/auth/abstract/request.rb
  79. +58 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/auth/basic.rb
  80. +124 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/auth/digest/md5.rb
  81. +51 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/auth/digest/nonce.rb
  82. +55 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/auth/digest/params.rb
  83. +40 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/auth/digest/request.rb
  84. +480 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/auth/openid.rb
  85. +63 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/builder.rb
  86. +36 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/cascade.rb
  87. +49 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/chunked.rb
  88. +61 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/commonlogger.rb
  89. +47 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/conditionalget.rb
  90. +29 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/content_length.rb
  91. +23 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/content_type.rb
  92. +96 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/deflater.rb
  93. +153 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/directory.rb
  94. +88 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/file.rb
  95. +69 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler.rb
  96. +61 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/cgi.rb
  97. +8 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/evented_mongrel.rb
  98. +88 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/fastcgi.rb
  99. +55 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/lsws.rb
  100. +84 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/mongrel.rb
  101. +59 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/scgi.rb
  102. +8 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/swiftiplied_mongrel.rb
  103. +18 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/thin.rb
  104. +67 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb
  105. +19 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/head.rb
  106. +537 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lint.rb
  107. +65 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lobster.rb
  108. +16 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb
  109. +27 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/methodoverride.rb
  110. +204 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/mime.rb
  111. +184 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/mock.rb
  112. +57 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/recursive.rb
  113. +106 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/reloader.rb
  114. +254 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/request.rb
  115. +183 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/response.rb
  116. +98 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/rewindable_input.rb
  117. +142 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/session/abstract/id.rb
  118. +91 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/session/cookie.rb
  119. +109 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/session/memcache.rb
  120. +100 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/session/pool.rb
  121. +349 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/showexceptions.rb
  122. +106 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/showstatus.rb
  123. +38 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/static.rb
  124. +55 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb
  125. +516 −0 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/utils.rb
  126. +4 −10 actionpack/lib/action_view.rb
  127. +3 −0 actionpack/lib/action_view/base.rb
  128. +7 −6 actionpack/lib/action_view/helpers/form_helper.rb
  129. +2 −0 actionpack/lib/action_view/helpers/form_options_helper.rb
  130. +1 −1 actionpack/lib/action_view/helpers/tag_helper.rb
  131. +1 −1 actionpack/lib/action_view/paths.rb
  132. +20 −12 actionpack/lib/action_view/render/partials.rb
  133. +5 −0 actionpack/lib/action_view/render/rendering.rb
  134. +1 −0 actionpack/lib/action_view/template/handlers/erb.rb
  135. +5 −2 actionpack/lib/action_view/template/text.rb
  136. +1 −1 actionpack/lib/action_view/test_case.rb
  137. +22 −26 actionpack/test/abstract_controller/abstract_controller_test.rb
  138. +29 −10 actionpack/test/abstract_controller/callbacks_test.rb
  139. +3 −3 actionpack/test/abstract_controller/helper_test.rb
  140. +15 −15 actionpack/test/abstract_controller/layouts_test.rb
  141. +4 −8 actionpack/test/abstract_controller/test_helper.rb
  142. +5 −1 actionpack/test/abstract_unit.rb
  143. +131 −0 actionpack/test/abstract_unit2.rb
  144. +1 −0 actionpack/test/activerecord/polymorphic_routes_test.rb
  145. +20 −12 actionpack/test/controller/action_pack_assertions_test.rb
  146. +1 −0 actionpack/test/controller/addresses_render_test.rb
  147. +6 −6 actionpack/test/controller/base_test.rb
  148. +40 −2 actionpack/test/controller/caching_test.rb
  149. +1 −0 actionpack/test/controller/capture_test.rb
  150. +10 −0 actionpack/test/controller/content_type_test.rb
  151. +8 −9 actionpack/test/controller/cookie_test.rb
  152. +0 −6 actionpack/test/controller/deprecation/deprecated_base_methods_test.rb
  153. +0 −13 actionpack/test/controller/dispatcher_test.rb
  154. +20 −13 actionpack/test/controller/filters_test.rb
  155. +29 −12 actionpack/test/controller/helper_test.rb
  156. +1 −11 actionpack/test/controller/integration_test.rb
  157. +1 −2 actionpack/test/controller/layout_test.rb
  158. +0 −5 actionpack/test/controller/redirect_test.rb
  159. +37 −0 actionpack/test/controller/render_js_test.rb
  160. +80 −0 actionpack/test/controller/render_json_test.rb
  161. +222 −0 actionpack/test/controller/render_other_test.rb
  162. +89 −322 actionpack/test/controller/render_test.rb
  163. +81 −0 actionpack/test/controller/render_xml_test.rb
  164. +47 −299 actionpack/test/controller/rescue_test.rb
  165. +8 −0 actionpack/test/controller/resources_test.rb
  166. +4 −4 actionpack/test/controller/routing_test.rb
  167. +4 −4 actionpack/test/controller/send_file_test.rb
  168. +5 −30 actionpack/test/controller/test_test.rb
  169. +1 −1 actionpack/test/dispatch/request_test.rb
  170. +103 −0 actionpack/test/dispatch/show_exceptions_test.rb
  171. +45 −0 actionpack/test/dispatch/test_request_test.rb
  172. +92 −23 actionpack/test/lib/fixture_template.rb
  173. +25 −26 actionpack/test/new_base/base_test.rb
  174. +111 −0 actionpack/test/new_base/content_type_test.rb
  175. +47 −0 actionpack/test/new_base/etag_test.rb
  176. +1 −0 actionpack/test/new_base/redirect_test.rb
  177. +23 −8 actionpack/test/new_base/render_action_test.rb
  178. +110 −0 actionpack/test/new_base/render_file_test.rb
  179. +21 −9 actionpack/test/new_base/render_implicit_action_test.rb
  180. +31 −3 actionpack/test/new_base/render_layout_test.rb
  181. +27 −0 actionpack/test/new_base/render_partial_test.rb
  182. +90 −52 actionpack/test/new_base/render_template_test.rb
  183. +88 −0 actionpack/test/new_base/render_test.rb
  184. +42 −37 actionpack/test/new_base/render_text_test.rb
  185. +11 −0 actionpack/test/new_base/render_xml_test.rb
  186. +34 −35 actionpack/test/new_base/test_helper.rb
  187. +5 −1 actionpack/test/template/body_parts_test.rb
  188. +22 −0 actionpack/test/template/form_options_helper_test.rb
  189. +26 −20 actionpack/test/template/output_buffer_test.rb
  190. +6 −0 activemodel/Rakefile
  191. +2 −11 activemodel/lib/active_model/core.rb
  192. +1 −0 activemodel/test/state_machine/event_test.rb
  193. +1 −0 activemodel/test/state_machine/state_transition_test.rb
  194. +19 −7 activerecord/Rakefile
  195. +14 −0 activerecord/examples/simple.rb
  196. +3 −11 activerecord/lib/active_record.rb
  197. +1 −3 activerecord/lib/active_record/aggregations.rb
  198. +4 −4 activerecord/lib/active_record/association_preload.rb
  199. +37 −13 activerecord/lib/active_record/associations.rb
  200. +6 −2 activerecord/lib/active_record/associations/association_collection.rb
  201. +14 −0 activerecord/lib/active_record/associations/association_proxy.rb
  202. +11 −1 activerecord/lib/active_record/associations/belongs_to_association.rb
  203. +5 −0 activerecord/lib/active_record/associations/has_many_association.rb
  204. +5 −5 activerecord/lib/active_record/associations/has_many_through_association.rb
  205. +10 −1 activerecord/lib/active_record/associations/has_one_association.rb
  206. +18 −12 activerecord/lib/active_record/attribute_methods.rb
  207. +6 −7 activerecord/lib/active_record/autosave_association.rb
  208. +19 −15 activerecord/lib/active_record/base.rb
  209. +1 −3 activerecord/lib/active_record/batches.rb
  210. +2 −3 activerecord/lib/active_record/calculations.rb
  211. +7 −5 activerecord/lib/active_record/callbacks.rb
  212. +7 −5 activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
  213. +2 −0 activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
  214. +2 −2 activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
  215. +2 −0 activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
  216. +1 −0 activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
  217. +1 −0 activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
  218. +3 −3 activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
  219. +1 −0 activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
  220. +14 −11 activerecord/lib/active_record/dirty.rb
  221. +19 −20 activerecord/lib/active_record/fixtures.rb
  222. +0 −26 activerecord/lib/active_record/i18n_interpolation_deprecation.rb
  223. +8 −8 activerecord/lib/active_record/locking/optimistic.rb
  224. +5 −5 activerecord/lib/active_record/migration.rb
  225. +9 −7 activerecord/lib/active_record/named_scope.rb
  226. +18 −5 activerecord/lib/active_record/nested_attributes.rb
  227. +1 −3 activerecord/lib/active_record/observer.rb
  228. +22 −3 activerecord/lib/active_record/reflection.rb
  229. +2 −2 activerecord/lib/active_record/schema_dumper.rb
  230. +9 −8 activerecord/lib/active_record/serialization.rb
  231. +4 −3 activerecord/lib/active_record/serializers/json_serializer.rb
  232. +4 −1 activerecord/lib/active_record/serializers/xml_serializer.rb
  233. +7 −5 activerecord/lib/active_record/timestamp.rb
  234. +5 −7 activerecord/lib/active_record/transactions.rb
  235. +9 −9 activerecord/lib/active_record/validations.rb
  236. +1 −0 activerecord/test/cases/aggregations_test.rb
  237. +7 −7 activerecord/test/cases/associations/eager_load_nested_include_test.rb
  238. +12 −0 activerecord/test/cases/associations/eager_test.rb
  239. +1 −0 activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
  240. +313 −0 activerecord/test/cases/associations/inverse_associations_test.rb
  241. +1 −0 activerecord/test/cases/base_test.rb
  242. +9 −2 activerecord/test/cases/finder_test.rb
  243. +5 −0 activerecord/test/cases/helper.rb
  244. +3 −3 activerecord/test/cases/method_scoping_test.rb
  245. +2 −1 activerecord/test/cases/named_scope_test.rb
  246. +18 −1 activerecord/test/cases/nested_attributes_test.rb
  247. +29 −0 activerecord/test/cases/pooled_connections_test.rb
  248. +1 −5 activerecord/test/cases/repair_helper.rb
  249. +8 −26 activerecord/test/cases/validations_i18n_test.rb
  250. +7 −0 activerecord/test/fixtures/faces.yml
  251. +29 −0 activerecord/test/fixtures/interests.yml
  252. +5 −0 activerecord/test/fixtures/men.yml
  253. +5 −0 activerecord/test/fixtures/zines.yml
  254. +2 −0 activerecord/test/models/company_in_module.rb
  255. +5 −0 activerecord/test/models/face.rb
  256. +4 −0 activerecord/test/models/interest.rb
  257. +7 −0 activerecord/test/models/man.rb
  258. +2 −0 activerecord/test/models/pirate.rb
  259. +3 −0 activerecord/test/models/zine.rb
  260. +21 −0 activerecord/test/schema/schema.rb
  261. +9 −1 activeresource/Rakefile
  262. +16 −0 activeresource/examples/simple.rb
  263. +4 −19 activeresource/lib/active_resource.rb
  264. +17 −5 activeresource/lib/active_resource/base.rb
  265. +4 −56 activeresource/lib/active_resource/connection.rb
  266. +4 −0 activeresource/lib/active_resource/custom_methods.rb
  267. +55 −0 activeresource/lib/active_resource/exceptions.rb
  268. +4 −4 activeresource/lib/active_resource/formats.rb
  269. +2 −0 activeresource/lib/active_resource/formats/xml_format.rb
  270. +6 −1 activeresource/lib/active_resource/http_mock.rb
  271. +7 −0 activeresource/lib/active_resource/validations.rb
  272. +3 −6 activeresource/test/abstract_unit.rb
  273. +1 −0 activeresource/test/base/custom_methods_test.rb
  274. +2 −0 activeresource/test/base/load_test.rb
  275. +2 −1 activeresource/test/base_test.rb
  276. +2 −0 activesupport/CHANGELOG
  277. +1 −1 activesupport/Rakefile
  278. +1 −0 activesupport/lib/active_support.rb
  279. +2 −2 activesupport/lib/active_support/core_ext/date/calculations.rb
  280. +3 −3 activesupport/lib/active_support/core_ext/date_time/conversions.rb
  281. +1 −1 activesupport/lib/active_support/core_ext/hash/conversions.rb
  282. +0 −1 activesupport/lib/active_support/core_ext/module.rb
  283. +0 −26 activesupport/lib/active_support/core_ext/module/setup.rb
  284. +3 −0 activesupport/lib/active_support/core_ext/object/conversions.rb
  285. +1 −1 activesupport/lib/active_support/core_ext/time/conversions.rb
  286. +25 −0 activesupport/lib/active_support/dependency_module.rb
  287. +1 −0 activesupport/lib/active_support/memoizable.rb
  288. +2 −10 activesupport/lib/active_support/new_callbacks.rb
  289. +14 −0 activesupport/lib/active_support/ordered_hash.rb
  290. +2 −2 activesupport/lib/active_support/values/time_zone.rb
  291. +16 −0 activesupport/test/core_ext/hash_ext_test.rb
  292. +77 −0 activesupport/test/dependency_module_test.rb
  293. +38 −2 activesupport/test/new_callbacks_test.rb
  294. +10 −0 activesupport/test/ordered_hash_test.rb
  295. +5 −0 railties/CHANGELOG
  296. +7 −1 railties/Rakefile
  297. +7 −0 railties/configs/seeds.rb
  298. +3 −2 railties/lib/console_app.rb
  299. +2 −2 railties/lib/initializer.rb
  300. +2 −0 railties/lib/rails/plugin.rb
Sorry, we could not display the entire diff because too many files (307) changed.
View
4 Rakefile
@@ -1,6 +1,5 @@
require 'rake'
require 'rake/rdoctask'
-require 'rake/contrib/sshpublisher'
env = %(PKG_BUILD="#{ENV['PKG_BUILD']}") if ENV['PKG_BUILD']
@@ -13,7 +12,7 @@ end
desc 'Run all tests by default'
task :default => :test
-%w(test rdoc pgem package release).each do |task_name|
+%w(test isolated_test rdoc pgem package release).each do |task_name|
desc "Run #{task_name} task for all projects"
task task_name do
PROJECTS.each do |project|
@@ -74,6 +73,7 @@ end
desc "Publish API docs for Rails as a whole and for each component"
task :pdoc => :rdoc do
+ require 'rake/contrib/sshpublisher'
Rake::SshDirPublisher.new("wrath.rubyonrails.org", "public_html/api", "doc/rdoc").upload
PROJECTS.each do |project|
system %(cd #{project} && #{env} #{$0} pdoc)
View
6 actionmailer/Rakefile
@@ -28,6 +28,12 @@ Rake::TestTask.new { |t|
t.warning = false
}
+task :isolated_test do
+ ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
+ Dir.glob("test/*_test.rb").all? do |file|
+ system(ruby, '-Ilib:test', file)
+ end or raise "Failures"
+end
# Generate the RDoc documentation
Rake::RDocTask.new { |rdoc|
View
1 actionmailer/lib/action_mailer/vendor/tmail.rb
@@ -12,6 +12,7 @@ module TMail
require 'tmail'
+require 'active_support/core_ext/kernel/reporting'
silence_warnings do
TMail::Encoder.const_set("MAX_LINE_LEN", 200)
end
View
20 actionpack/Rakefile
@@ -4,7 +4,6 @@ require 'rake/testtask'
require 'rake/rdoctask'
require 'rake/packagetask'
require 'rake/gempackagetask'
-require 'rake/contrib/sshpublisher'
require File.join(File.dirname(__FILE__), 'lib', 'action_pack', 'version')
PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
@@ -23,18 +22,24 @@ task :default => [ :test ]
# Run the unit tests
desc "Run all unit tests"
-task :test => [:test_action_pack, :test_active_record_integration]
+task :test => [:test_action_pack, :test_active_record_integration, :test_new_base]
Rake::TestTask.new(:test_action_pack) do |t|
t.libs << "test"
# make sure we include the tests in alphabetical order as on some systems
# this will not happen automatically and the tests (as a whole) will error
- t.test_files = Dir.glob( "test/[cdft]*/**/*_test.rb" ).sort
+ t.test_files = Dir.glob( "test/{controller,dispatch,template}/**/*_test.rb" ).sort
t.verbose = true
#t.warning = true
end
+task :isolated_test do
+ ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
+ Dir.glob("test/{controller,dispatch,template}/**/*_test.rb").all? do |file|
+ system(ruby, '-Ilib:test', file)
+ end or raise "Failures"
+end
desc 'ActiveRecord Integration Tests'
Rake::TestTask.new(:test_active_record_integration) do |t|
@@ -43,6 +48,13 @@ Rake::TestTask.new(:test_active_record_integration) do |t|
t.verbose = true
end
+desc 'New Controller Tests'
+Rake::TestTask.new(:test_new_base) do |t|
+ t.libs << "test"
+ t.test_files = Dir.glob("test/{abstract_controller,new_base}/*_test.rb")
+ t.verbose = true
+end
+
# Genereate the RDoc documentation
@@ -136,12 +148,14 @@ task :update_js => [ :update_scriptaculous ]
desc "Publish the API documentation"
task :pgem => [:package] do
+ require 'rake/contrib/sshpublisher'
Rake::SshFilePublisher.new("gems.rubyonrails.org", "/u/sites/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
`ssh gems.rubyonrails.org '/u/sites/gems/gemupdate.sh'`
end
desc "Publish the API documentation"
task :pdoc => [:rdoc] do
+ require 'rake/contrib/sshpublisher'
Rake::SshDirPublisher.new("wrath.rubyonrails.org", "public_html/ap", "doc").upload
end
View
34 actionpack/examples/minimal.rb
@@ -0,0 +1,34 @@
+$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
+require 'action_controller'
+require 'action_controller/new_base' if ENV['NEW']
+require 'benchmark'
+
+class BaseController < ActionController::Base
+ def index
+ render :text => ''
+ end
+end
+
+n = (ENV['N'] || 10000).to_i
+input = StringIO.new('')
+
+def call_index(controller, input, n)
+ n.times do
+ controller.action(:index).call({ 'rack.input' => input })
+ end
+
+ puts controller.name
+ status, headers, body = controller.action(:index).call({ 'rack.input' => input })
+
+ puts status
+ puts headers.to_yaml
+ puts '---'
+ body.each do |part|
+ puts part
+ end
+ puts '---'
+end
+
+elapsed = Benchmark.realtime { call_index BaseController, input, n }
+
+puts "%dms elapsed, %d requests/sec" % [1000 * elapsed, n / elapsed]
View
15 actionpack/lib/action_controller.rb
@@ -21,16 +21,9 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
-begin
- require 'active_support'
-rescue LoadError
- activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
- if File.directory?(activesupport_path)
- $:.unshift activesupport_path
- require 'active_support'
- end
-end
-require 'active_support/core/all'
+activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
+$:.unshift activesupport_path if File.directory?(activesupport_path)
+require 'active_support'
require File.join(File.dirname(__FILE__), "action_pack")
@@ -60,7 +53,7 @@ def self.load_all!
autoload :Redirector, 'action_controller/base/redirect'
autoload :Renderer, 'action_controller/base/render'
autoload :RequestForgeryProtection, 'action_controller/base/request_forgery_protection'
- autoload :Rescue, 'action_controller/dispatch/rescue'
+ autoload :Rescue, 'action_controller/base/rescue'
autoload :Resources, 'action_controller/routing/resources'
autoload :Responder, 'action_controller/base/responder'
autoload :Routing, 'action_controller/routing'
View
3 actionpack/lib/action_controller/abstract.rb
@@ -1,3 +1,6 @@
+require "active_support/core_ext/module/attr_internal"
+require "active_support/core_ext/module/delegation"
+
module AbstractController
autoload :Base, "action_controller/abstract/base"
autoload :Callbacks, "action_controller/abstract/callbacks"
View
89 actionpack/lib/action_controller/abstract/base.rb
@@ -1,41 +1,112 @@
+require 'active_support/core_ext/module/attr_internal'
+
module AbstractController
+ class Error < StandardError; end
+
+ class DoubleRenderError < Error
+ DEFAULT_MESSAGE = "Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most 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\"."
+
+ def initialize(message = nil)
+ super(message || DEFAULT_MESSAGE)
+ end
+ end
+
class Base
attr_internal :response_body
attr_internal :response_obj
attr_internal :action_name
-
- def self.process(action)
- new.process(action)
+
+ class << self
+ attr_reader :abstract
+
+ def abstract!
+ @abstract = true
+ end
+
+ alias_method :abstract?, :abstract
+
+ def inherited(klass)
+ ::AbstractController::Base.subclasses << klass.to_s
+ super
+ end
+
+ def subclasses
+ @subclasses ||= []
+ end
+
+ def internal_methods
+ controller = self
+ controller = controller.superclass until controller.abstract?
+ controller.public_instance_methods(true)
+ end
+
+ def process(action)
+ new.process(action.to_s)
+ end
+
+ def hidden_actions
+ []
+ end
+
+ def action_methods
+ @action_methods ||=
+ # All public instance methods of this class, including ancestors
+ public_instance_methods(true).map { |m| m.to_s }.to_set -
+ # Except for public instance methods of Base and its ancestors
+ internal_methods.map { |m| m.to_s } +
+ # Be sure to include shadowed public instance methods of this class
+ public_instance_methods(false).map { |m| m.to_s } -
+ # And always exclude explicitly hidden actions
+ hidden_actions
+ end
end
- def self.inherited(klass)
- end
+ abstract!
def initialize
self.response_obj = {}
end
def process(action_name)
+ action_name = action_name.to_s
+
unless respond_to_action?(action_name)
raise ActionNotFound, "The action '#{action_name}' could not be found"
end
@_action_name = action_name
process_action
- self.response_obj[:body] = self.response_body
self
end
private
+ def action_methods
+ self.class.action_methods
+ end
+
+ def action_method?(action)
+ action_methods.include?(action)
+ end
+
+ # It is possible for respond_to?(action_name) to be false and
+ # respond_to?(:action_missing) to be false if respond_to_action?
+ # is overridden in a subclass. For instance, ActionController::Base
+ # overrides it to include the case where a template matching the
+ # action_name is found.
def process_action
- respond_to?(action_name) ? send(action_name) : send(:action_missing, action_name)
+ if action_method?(action_name) then send(action_name)
+ elsif respond_to?(:action_missing, true) then action_missing(action_name)
+ end
end
+ # Override this to change the conditions that will raise an
+ # ActionNotFound error. If you accept a difference case,
+ # you must handle it by also overriding process_action and
+ # handling the case.
def respond_to_action?(action_name)
- respond_to?(action_name) || respond_to?(:action_missing, true)
+ action_method?(action_name) || respond_to?(:action_missing, true)
end
-
end
end
View
15 actionpack/lib/action_controller/abstract/callbacks.rb
@@ -1,10 +1,13 @@
module AbstractController
module Callbacks
- setup do
- include ActiveSupport::NewCallbacks
- define_callbacks :process_action
+ extend ActiveSupport::DependencyModule
+
+ depends_on ActiveSupport::NewCallbacks
+
+ included do
+ define_callbacks :process_action, "response_body"
end
-
+
def process_action
_run_process_action_callbacks(action_name) do
super
@@ -14,11 +17,11 @@ def process_action
module ClassMethods
def _normalize_callback_options(options)
if only = options[:only]
- only = Array(only).map {|o| "action_name == :#{o}"}.join(" || ")
+ only = Array(only).map {|o| "action_name == '#{o}'"}.join(" || ")
options[:per_key] = {:if => only}
end
if except = options[:except]
- except = Array(except).map {|e| "action_name == :#{e}"}.join(" || ")
+ except = Array(except).map {|e| "action_name == '#{e}'"}.join(" || ")
options[:per_key] = {:unless => except}
end
end
View
15 actionpack/lib/action_controller/abstract/helpers.rb
@@ -1,19 +1,14 @@
module AbstractController
module Helpers
+ extend ActiveSupport::DependencyModule
+
depends_on Renderer
-
- setup do
+
+ included do
extlib_inheritable_accessor :master_helper_module
self.master_helper_module = Module.new
end
-
- # def self.included(klass)
- # klass.class_eval do
- # extlib_inheritable_accessor :master_helper_module
- # self.master_helper_module = Module.new
- # end
- # end
-
+
def _action_view
@_action_view ||= begin
av = super
View
14 actionpack/lib/action_controller/abstract/layouts.rb
@@ -1,8 +1,9 @@
module AbstractController
module Layouts
-
+ extend ActiveSupport::DependencyModule
+
depends_on Renderer
-
+
module ClassMethods
def layout(layout)
unless [String, Symbol, FalseClass, NilClass].include?(layout.class)
@@ -50,13 +51,16 @@ def _layout
end
def _render_template(template, options)
- _action_view._render_template_with_layout(template, options[:_layout])
+ _action_view._render_template_from_controller(template, options[:_layout], options, options[:_partial])
end
private
def _layout() end # This will be overwritten
+ # :api: plugin
+ # ====
+ # Override this to mutate the inbound layout name
def _layout_for_name(name)
unless [String, FalseClass, NilClass].include?(name.class)
raise ArgumentError, "String, false, or nil expected; you passed #{name.inspect}"
@@ -67,10 +71,10 @@ def _layout_for_name(name)
def _default_layout(require_layout = false)
if require_layout && !_layout
- raise ArgumentError,
+ raise ArgumentError,
"There was no default layout for #{self.class} in #{view_paths.inspect}"
end
-
+
begin
layout = _layout_for_name(_layout)
rescue NameError => e
View
41 actionpack/lib/action_controller/abstract/logger.rb
@@ -1,7 +1,44 @@
+require 'active_support/core_ext/class/attribute_accessors'
+
module AbstractController
module Logger
- setup do
+ extend ActiveSupport::DependencyModule
+
+ class DelayedLog
+ def initialize(&blk)
+ @blk = blk
+ end
+
+ def to_s
+ @blk.call
+ end
+ alias to_str to_s
+ end
+
+ included do
cattr_accessor :logger
end
+
+ def process(action)
+ ret = super
+
+ if logger
+ log = DelayedLog.new do
+ "\n\nProcessing #{self.class.name}\##{action_name} " \
+ "to #{request.formats} " \
+ "(for #{request_origin}) [#{request.method.to_s.upcase}]"
+ end
+
+ logger.info(log)
+ end
+
+ ret
+ end
+
+ def request_origin
+ # this *needs* to be cached!
+ # otherwise you'd get different results if calling it more than once
+ @request_origin ||= "#{request.remote_ip} at #{Time.now.to_s(:db)}"
+ end
end
-end
+end
View
35 actionpack/lib/action_controller/abstract/renderer.rb
@@ -2,22 +2,28 @@
module AbstractController
module Renderer
+ extend ActiveSupport::DependencyModule
+
depends_on AbstractController::Logger
-
- setup do
+
+ included do
attr_internal :formats
-
+
extlib_inheritable_accessor :_view_paths
-
+
self._view_paths ||= ActionView::PathSet.new
end
-
+
def _action_view
@_action_view ||= ActionView::Base.new(self.class.view_paths, {}, self)
end
- def render(options = {})
- self.response_body = render_to_body(options)
+ def render(*args)
+ if response_body
+ raise AbstractController::DoubleRenderError, "OMG"
+ end
+
+ self.response_body = render_to_body(*args)
end
# Raw rendering of a template to a Rack-compatible body.
@@ -28,9 +34,16 @@ def render(options = {})
# :api: plugin
def render_to_body(options = {})
name = options[:_template_name] || action_name
-
- template = options[:_template] || view_paths.find_by_parts(name.to_s, {:formats => formats}, options[:_prefix])
- _render_template(template, options)
+
+ # TODO: Refactor so we can just use the normal template logic for this
+ if options[:_partial_object]
+ _action_view._render_partial_from_controller(options)
+ else
+ options[:_template] ||= view_paths.find_by_parts(name.to_s, {:formats => formats},
+ options[:_prefix], options[:_partial])
+
+ _render_template(options[:_template], options)
+ end
end
# Raw rendering of a template to a string.
@@ -44,7 +57,7 @@ def render_to_string(options = {})
end
def _render_template(template, options)
- _action_view._render_template_with_layout(template)
+ _action_view._render_template_from_controller(template, nil, options, options[:_partial])
end
def view_paths() _view_paths end
View
47 actionpack/lib/action_controller/base/base.rb
@@ -1,5 +1,7 @@
require 'action_controller/deprecated'
require 'set'
+require 'active_support/core_ext/class/inheritable_attributes'
+require 'active_support/core_ext/module/attr_internal'
module ActionController #:nodoc:
class ActionControllerError < StandardError #:nodoc:
@@ -30,10 +32,6 @@ def initialize(*allowed_methods)
def allowed_methods_header
allowed_methods.map { |method_symbol| method_symbol.to_s.upcase } * ', '
end
-
- def handle_response!(response)
- response.headers['Allow'] ||= allowed_methods_header
- end
end
class NotImplemented < MethodNotAllowed #:nodoc:
@@ -369,19 +367,23 @@ def session
attr_reader :template
- class << self
- def call(env)
- # HACK: For global rescue to have access to the original request and response
- request = env["action_controller.rescue.request"] ||= ActionDispatch::Request.new(env)
- response = env["action_controller.rescue.response"] ||= ActionDispatch::Response.new
- process(request, response)
- end
+ def action(name, env)
+ # HACK: For global rescue to have access to the original request and response
+ request = env["action_controller.rescue.request"] ||= ActionDispatch::Request.new(env)
+ response = env["action_controller.rescue.response"] ||= ActionDispatch::Response.new
+ self.action_name = name && name.to_s
+ process(request, response).to_a
+ end
- # Factory for the standard create, process loop where the controller is discarded after processing.
- def process(request, response) #:nodoc:
- new.process(request, response)
- end
+ class << self
+ def action(name = nil)
+ @actions ||= {}
+ @actions[name] ||= proc do |env|
+ new.action(name, env)
+ end
+ end
+
# Converts the class name from something like "OneModule::TwoModule::NeatController" to "NeatController".
def controller_class_name
@controller_class_name ||= name.demodulize
@@ -511,14 +513,19 @@ def exempt_from_layout(*types)
end
public
+ def call(env)
+ request = ActionDispatch::Request.new(env)
+ response = ActionDispatch::Response.new
+ process(request, response).to_a
+ end
+
# Extracts the action_name from the request parameters and performs that action.
def process(request, response, method = :perform_action, *arguments) #:nodoc:
response.request = request
assign_shortcuts(request, response)
initialize_template_class(response)
initialize_current_url
- assign_names
log_processing
send(method, *arguments)
@@ -817,9 +824,9 @@ def _process_options(options)
end
def initialize_template_class(response)
- @template = response.template = ActionView::Base.new(self.class.view_paths, {}, self, formats)
+ @template = ActionView::Base.new(self.class.view_paths, {}, self, formats)
+ response.template = @template if response.respond_to?(:template=)
@template.helpers.send :include, self.class.master_helper_module
- response.redirected_to = nil
@performed_render = @performed_redirect = false
end
@@ -882,10 +889,6 @@ def performed?
@performed_render || @performed_redirect
end
- def assign_names
- @action_name = (params['action'] || 'index')
- end
-
def reset_variables_added_to_assigns
@template.instance_variable_set("@assigns_added", nil)
end
View
2 actionpack/lib/action_controller/base/chained/benchmarking.rb
@@ -1,4 +1,4 @@
-require 'benchmark'
+require 'active_support/core_ext/benchmark'
module ActionController #:nodoc:
# The benchmarking module times the performance of actions and reports to the logger. If the Active Record
View
6 actionpack/lib/action_controller/base/http_authentication.rb
@@ -1,3 +1,5 @@
+require 'active_support/base64'
+
module ActionController
module HttpAuthentication
# Makes it dead easy to do HTTP Basic authentication.
@@ -276,7 +278,7 @@ def nonce(time = Time.now)
t = time.to_i
hashed = [t, secret_key]
digest = ::Digest::MD5.hexdigest(hashed.join(":"))
- Base64.encode64("#{t}:#{digest}").gsub("\n", '')
+ ActiveSupport::Base64.encode64("#{t}:#{digest}").gsub("\n", '')
end
# Might want a shorter timeout depending on whether the request
@@ -285,7 +287,7 @@ def nonce(time = Time.now)
# allow a user to use new nonce without prompting user again for their
# username and password.
def validate_nonce(request, value, seconds_to_timeout=5*60)
- t = Base64.decode64(value).split(":").first.to_i
+ t = ActiveSupport::Base64.decode64(value).split(":").first.to_i
nonce(t) == value && (t - Time.now.to_i).abs <= seconds_to_timeout
end
View
4 actionpack/lib/action_controller/base/layout.rb
@@ -1,3 +1,7 @@
+require 'active_support/core_ext/enumerable'
+require 'active_support/core_ext/class/delegating_attributes'
+require 'active_support/core_ext/class/inheritable_attributes'
+
module ActionController #:nodoc:
module Layout #:nodoc:
def self.included(base)
View
8 actionpack/lib/action_controller/base/redirect.rb
@@ -48,8 +48,6 @@ def redirect_to(options = {}, response_status = {}) #:doc:
status = 302
end
- response.redirected_to = options
-
case options
# The scheme name consist of a letter followed by any combination of
# letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
@@ -72,7 +70,9 @@ def redirect_to(options = {}, response_status = {}) #:doc:
def redirect_to_full_url(url, status)
raise DoubleRenderError if performed?
logger.info("Redirected to #{url}") if logger && logger.info?
- response.redirect(url, interpret_status(status))
+ response.status = interpret_status(status)
+ response.location = url.gsub(/[\r\n]/, '')
+ response.body = "<html><body>You are being <a href=\"#{CGI.escapeHTML(url)}\">redirected</a>.</body></html>"
@performed_redirect = true
end
@@ -82,8 +82,6 @@ def redirect_to_full_url(url, status)
# The response body is not reset here, see +erase_render_results+
def erase_redirect_results #:nodoc:
@performed_redirect = false
- response.redirected_to = nil
- response.redirected_to_method_params = nil
response.status = DEFAULT_RENDER_STATUS_CODE
response.headers.delete('Location')
end
View
3 actionpack/lib/action_controller/base/render.rb
@@ -253,7 +253,8 @@ def render(options = nil, extra_options = {}, &block) #:doc:
response.content_type ||= Mime::JS
render_for_text(js)
- elsif json = options[:json]
+ elsif options.include?(:json)
+ json = options[:json]
json = ActiveSupport::JSON.encode(json) unless json.respond_to?(:to_str)
json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
response.content_type ||= Mime::JSON
View
50 actionpack/lib/action_controller/base/rescue.rb
@@ -0,0 +1,50 @@
+module ActionController #:nodoc:
+ # Actions that fail to perform as expected throw exceptions. These
+ # exceptions can either be rescued for the public view (with a nice
+ # user-friendly explanation) or for the developers view (with tons of
+ # debugging information). The developers view is already implemented by
+ # the Action Controller, but the public view should be tailored to your
+ # specific application.
+ #
+ # The default behavior for public exceptions is to render a static html
+ # file with the name of the error code thrown. If no such file exists, an
+ # empty response is sent with the correct status code.
+ #
+ # You can override what constitutes a local request by overriding the
+ # <tt>local_request?</tt> method in your own controller. Custom rescue
+ # behavior is achieved by overriding the <tt>rescue_action_in_public</tt>
+ # and <tt>rescue_action_locally</tt> methods.
+ module Rescue
+ def self.included(base) #:nodoc:
+ base.send :include, ActiveSupport::Rescuable
+ base.extend(ClassMethods)
+
+ base.class_eval do
+ alias_method_chain :perform_action, :rescue
+ end
+ end
+
+ module ClassMethods
+ def rescue_action(env)
+ exception = env.delete('action_dispatch.rescue.exception')
+ request = ActionDispatch::Request.new(env)
+ response = ActionDispatch::Response.new
+ new.process(request, response, :rescue_action, exception).to_a
+ end
+ end
+
+ protected
+ # Exception handler called when the performance of an action raises
+ # an exception.
+ def rescue_action(exception)
+ rescue_with_handler(exception) || raise(exception)
+ end
+
+ private
+ def perform_action_with_rescue
+ perform_action_without_rescue
+ rescue Exception => exception
+ rescue_action(exception)
+ end
+ end
+end
View
10 actionpack/lib/action_controller/caching/actions.rb
@@ -61,7 +61,9 @@ def caches_action(*actions)
filter_options = { :only => actions, :if => options.delete(:if), :unless => options.delete(:unless) }
cache_filter = ActionCacheFilter.new(:layout => options.delete(:layout), :cache_path => options.delete(:cache_path), :store_options => options)
- around_filter(cache_filter, filter_options)
+ around_filter(filter_options) do |controller, action|
+ cache_filter.filter(controller, action)
+ end
end
end
@@ -83,6 +85,12 @@ def initialize(options, &block)
@options = options
end
+ def filter(controller, action)
+ should_continue = before(controller)
+ action.call if should_continue
+ after(controller)
+ end
+
def before(controller)
cache_path = ActionCachePath.new(controller, path_options_for(controller, @options.slice(:cache_path)))
if cache = controller.read_fragment(cache_path.path, @options[:store_options])
View
55 actionpack/lib/action_controller/dispatch/dispatcher.rb
@@ -5,9 +5,9 @@ class Dispatcher
class << self
def define_dispatcher_callbacks(cache_classes)
unless cache_classes
- unless self.middleware.include?(ActionDispatch::Reloader)
- self.middleware.insert_after(ActionDispatch::Failsafe, ActionDispatch::Reloader)
- end
+ # Development mode callbacks
+ before_dispatch :reload_application
+ after_dispatch :cleanup_application
ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false
end
@@ -40,53 +40,44 @@ def to_prepare(identifier = nil, &block)
def run_prepare_callbacks
new.send :run_callbacks, :prepare_dispatch
end
-
- def reload_application
- # Run prepare callbacks before every request in development mode
- run_prepare_callbacks
-
- Routing::Routes.reload
- end
-
- def cleanup_application
- # Cleanup the application before processing the current request.
- ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord)
- ActiveSupport::Dependencies.clear
- ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord)
- end
end
+ cattr_accessor :router
+ self.router = Routing::Routes
+
cattr_accessor :middleware
self.middleware = ActionDispatch::MiddlewareStack.new do |middleware|
middlewares = File.join(File.dirname(__FILE__), "middlewares.rb")
- middleware.instance_eval(File.read(middlewares))
+ middleware.instance_eval(File.read(middlewares), middlewares, 1)
end
include ActiveSupport::Callbacks
define_callbacks :prepare_dispatch, :before_dispatch, :after_dispatch
def initialize
- @app = @@middleware.build(lambda { |env| self._call(env) })
+ @app = @@middleware.build(@@router)
freeze
end
def call(env)
+ run_callbacks :before_dispatch
@app.call(env)
+ ensure
+ run_callbacks :after_dispatch, :enumerator => :reverse_each
end
- def _call(env)
- begin
- run_callbacks :before_dispatch
- Routing::Routes.call(env)
- rescue Exception => exception
- if controller ||= (::ApplicationController rescue Base)
- controller.call_with_exception(env, exception).to_a
- else
- raise exception
- end
- ensure
- run_callbacks :after_dispatch, :enumerator => :reverse_each
- end
+ def reload_application
+ # Run prepare callbacks before every request in development mode
+ run_callbacks :prepare_dispatch
+
+ @@router.reload
+ end
+
+ def cleanup_application
+ # Cleanup the application before processing the current request.
+ ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord)
+ ActiveSupport::Dependencies.clear
+ ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord)
end
def flush_logger
View
7 actionpack/lib/action_controller/dispatch/middlewares.rb
@@ -3,10 +3,15 @@
}
use "ActionDispatch::Failsafe"
+use "ActionDispatch::ShowExceptions", lambda { ActionController::Base.consider_all_requests_local }
+use "ActionDispatch::Rescue", lambda {
+ controller = (::ApplicationController rescue ActionController::Base)
+ controller.method(:rescue_action)
+}
use lambda { ActionController::Base.session_store },
lambda { ActionController::Base.session_options }
use "ActionDispatch::ParamsParser"
use "Rack::MethodOverride"
-use "Rack::Head"
+use "Rack::Head"
View
185 actionpack/lib/action_controller/dispatch/rescue.rb
@@ -1,185 +0,0 @@
-module ActionController #:nodoc:
- # Actions that fail to perform as expected throw exceptions. These
- # exceptions can either be rescued for the public view (with a nice
- # user-friendly explanation) or for the developers view (with tons of
- # debugging information). The developers view is already implemented by
- # the Action Controller, but the public view should be tailored to your
- # specific application.
- #
- # The default behavior for public exceptions is to render a static html
- # file with the name of the error code thrown. If no such file exists, an
- # empty response is sent with the correct status code.
- #
- # You can override what constitutes a local request by overriding the
- # <tt>local_request?</tt> method in your own controller. Custom rescue
- # behavior is achieved by overriding the <tt>rescue_action_in_public</tt>
- # and <tt>rescue_action_locally</tt> methods.
- module Rescue
- LOCALHOST = '127.0.0.1'.freeze
-
- DEFAULT_RESCUE_RESPONSE = :internal_server_error
- DEFAULT_RESCUE_RESPONSES = {
- 'ActionController::RoutingError' => :not_found,
- 'ActionController::UnknownAction' => :not_found,
- 'ActiveRecord::RecordNotFound' => :not_found,
- 'ActiveRecord::StaleObjectError' => :conflict,
- 'ActiveRecord::RecordInvalid' => :unprocessable_entity,
- 'ActiveRecord::RecordNotSaved' => :unprocessable_entity,
- 'ActionController::MethodNotAllowed' => :method_not_allowed,
- 'ActionController::NotImplemented' => :not_implemented,
- 'ActionController::InvalidAuthenticityToken' => :unprocessable_entity
- }
-
- DEFAULT_RESCUE_TEMPLATE = 'diagnostics'
- DEFAULT_RESCUE_TEMPLATES = {
- 'ActionView::MissingTemplate' => 'missing_template',
- 'ActionController::RoutingError' => 'routing_error',
- 'ActionController::UnknownAction' => 'unknown_action',
- 'ActionView::TemplateError' => 'template_error'
- }
-
- RESCUES_TEMPLATE_PATH = ActionView::Template::FileSystemPath.new(
- File.join(File.dirname(__FILE__), "templates"))
-
- def self.included(base) #:nodoc:
- base.cattr_accessor :rescue_responses
- base.rescue_responses = Hash.new(DEFAULT_RESCUE_RESPONSE)
- base.rescue_responses.update DEFAULT_RESCUE_RESPONSES
-
- base.cattr_accessor :rescue_templates
- base.rescue_templates = Hash.new(DEFAULT_RESCUE_TEMPLATE)
- base.rescue_templates.update DEFAULT_RESCUE_TEMPLATES
-
- base.extend(ClassMethods)
- base.send :include, ActiveSupport::Rescuable
-
- base.class_eval do
- alias_method_chain :perform_action, :rescue
- end
- end
-
- module ClassMethods
- def call_with_exception(env, exception) #:nodoc:
- request = env["action_controller.rescue.request"] ||= ActionDispatch::Request.new(env)
- response = env["action_controller.rescue.response"] ||= ActionDispatch::Response.new
- new.process(request, response, :rescue_action, exception)
- end
- end
-
- protected
- # Exception handler called when the performance of an action raises
- # an exception.
- def rescue_action(exception)
- rescue_with_handler(exception) ||
- rescue_action_without_handler(exception)
- end
-
- # Overwrite to implement custom logging of errors. By default
- # logs as fatal.
- def log_error(exception) #:doc:
- ActiveSupport::Deprecation.silence do
- if ActionView::TemplateError === exception
- logger.fatal(exception.to_s)
- else
- logger.fatal(
- "\n#{exception.class} (#{exception.message}):\n " +
- clean_backtrace(exception).join("\n ") + "\n\n"
- )
- end
- end
- end
-
- # Overwrite to implement public exception handling (for requests
- # answering false to <tt>local_request?</tt>). By default will call
- # render_optional_error_file. Override this method to provide more
- # user friendly error messages.
- def rescue_action_in_public(exception) #:doc:
- render_optional_error_file response_code_for_rescue(exception)
- end
-
- # Attempts to render a static error page based on the
- # <tt>status_code</tt> thrown, or just return headers if no such file
- # exists. At first, it will try to render a localized static page.
- # For example, if a 500 error is being handled Rails and locale is :da,
- # it will first attempt to render the file at <tt>public/500.da.html</tt>
- # then attempt to render <tt>public/500.html</tt>. If none of them exist,
- # the body of the response will be left empty.
- def render_optional_error_file(status_code)
- status = interpret_status(status_code)
- locale_path = "#{Rails.public_path}/#{status[0,3]}.#{I18n.locale}.html" if I18n.locale
- path = "#{Rails.public_path}/#{status[0,3]}.html"
-
- if locale_path && File.exist?(locale_path)
- render :file => locale_path, :status => status, :content_type => Mime::HTML
- elsif File.exist?(path)
- render :file => path, :status => status, :content_type => Mime::HTML
- else
- head status
- end
- end
-
- # True if the request came from localhost, 127.0.0.1. Override this
- # method if you wish to redefine the meaning of a local request to
- # include remote IP addresses or other criteria.
- def local_request? #:doc:
- request.remote_addr == LOCALHOST && request.remote_ip == LOCALHOST
- end
-
- # Render detailed diagnostics for unhandled exceptions rescued from
- # a controller action.
- def rescue_action_locally(exception)
- @template.instance_variable_set("@exception", exception)
- @template.instance_variable_set("@rescues_path", RESCUES_TEMPLATE_PATH)
- @template.instance_variable_set("@contents",
- @template._render_template(template_path_for_local_rescue(exception)))
-
- response.content_type = Mime::HTML
- response.status = interpret_status(response_code_for_rescue(exception))
-
- content = @template._render_template(rescues_path("layout"))
- render_for_text(content)
- end
-
- def rescue_action_without_handler(exception)
- log_error(exception) if logger
- erase_results if performed?
-
- # Let the exception alter the response if it wants.
- # For example, MethodNotAllowed sets the Allow header.
- if exception.respond_to?(:handle_response!)
- exception.handle_response!(response)
- end
-
- if consider_all_requests_local || local_request?
- rescue_action_locally(exception)
- else
- rescue_action_in_public(exception)
- end
- end
-
- private
- def perform_action_with_rescue #:nodoc:
- perform_action_without_rescue
- rescue Exception => exception
- rescue_action(exception)
- end
-
- def rescues_path(template_name)
- RESCUES_TEMPLATE_PATH.find_by_parts("rescues/#{template_name}.erb")
- end
-
- def template_path_for_local_rescue(exception)
- rescues_path(rescue_templates[exception.class.name])
- end
-
- def response_code_for_rescue(exception)
- rescue_responses[exception.class.name]
- end
-
- def clean_backtrace(exception)
- defined?(Rails) && Rails.respond_to?(:backtrace_cleaner) ?
- Rails.backtrace_cleaner.clean(exception.backtrace) :
- exception.backtrace
- end
- end
-end
View
10 actionpack/lib/action_controller/dispatch/templates/rescues/diagnostics.erb
@@ -1,10 +0,0 @@
-<h1>
- <%=h @exception.class.to_s %>
- <% if request.parameters['controller'] %>
- in <%=h request.parameters['controller'].humanize %>Controller<% if request.parameters['action'] %>#<%=h request.parameters['action'] %><% end %>
- <% end %>
-</h1>
-<pre><%=h @exception.clean_message %></pre>
-
-<%= @template._render_template(@rescues_path.find_by_parts("rescues/_trace.erb")) %>
-<%= @template._render_template(@rescues_path.find_by_parts("rescues/_request_and_response.erb")) %>
View
33 actionpack/lib/action_controller/new_base.rb
@@ -1,7 +1,28 @@
module ActionController
- autoload :AbstractBase, "action_controller/new_base/base"
- autoload :HideActions, "action_controller/new_base/hide_actions"
- autoload :Layouts, "action_controller/new_base/layouts"
- autoload :Renderer, "action_controller/new_base/renderer"
- autoload :UrlFor, "action_controller/new_base/url_for"
-end
+ autoload :Base, "action_controller/new_base/base"
+ autoload :ConditionalGet, "action_controller/new_base/conditional_get"
+ autoload :HideActions, "action_controller/new_base/hide_actions"
+ autoload :Http, "action_controller/new_base/http"
+ autoload :Layouts, "action_controller/new_base/layouts"
+ autoload :Rails2Compatibility, "action_controller/new_base/compatibility"
+ autoload :Redirector, "action_controller/new_base/redirector"
+ autoload :Renderer, "action_controller/new_base/renderer"
+ autoload :Testing, "action_controller/new_base/testing"
+ autoload :UrlFor, "action_controller/new_base/url_for"
+
+ # Ported modules
+ # require 'action_controller/routing'
+ autoload :Dispatcher, 'action_controller/dispatch/dispatcher'
+ autoload :PolymorphicRoutes, 'action_controller/routing/generation/polymorphic_routes'
+ autoload :RecordIdentifier, 'action_controller/record_identifier'
+ autoload :Resources, 'action_controller/routing/resources'
+ autoload :SessionManagement, 'action_controller/base/session_management'
+ autoload :TestCase, 'action_controller/testing/test_case'
+ autoload :UrlRewriter, 'action_controller/routing/generation/url_rewriter'
+ autoload :UrlWriter, 'action_controller/routing/generation/url_rewriter'
+
+ require 'action_controller/routing'
+end
+
+require 'action_dispatch'
+require 'action_view'
View
157 actionpack/lib/action_controller/new_base/base.rb
@@ -1,60 +1,127 @@
module ActionController
- class AbstractBase < AbstractController::Base
+ class Base < Http
+ abstract!
- # :api: public
- attr_internal :request, :response, :params
-
- # :api: public
- def self.controller_name
- @controller_name ||= controller_path.split("/").last
- end
-
- # :api: public
- def controller_name() self.class.controller_name end
-
- # :api: public
- def self.controller_path
- @controller_path ||= self.name.sub(/Controller$/, '').underscore
- end
+ include AbstractController::Callbacks
+ include AbstractController::Helpers
+ include AbstractController::Logger
- # :api: public
- def controller_path() self.class.controller_path end
-
- # :api: private
- def self.action_methods
- @action_names ||= Set.new(self.public_instance_methods - self::CORE_METHODS)
+ include ActionController::HideActions
+ include ActionController::UrlFor
+ include ActionController::Redirector
+ include ActionController::Renderer
+ include ActionController::Layouts
+ include ActionController::ConditionalGet
+
+ # Legacy modules
+ include SessionManagement
+ include ActionDispatch::StatusCodes
+
+ # Rails 2.x compatibility
+ include ActionController::Rails2Compatibility
+
+ def self.inherited(klass)
+ ::ActionController::Base.subclasses << klass.to_s
+ super
end
- # :api: private
- def self.action_names() action_methods end
+ def self.subclasses
+ @subclasses ||= []
+ end
- # :api: private
- def action_methods() self.class.action_names end
-
- # :api: private
- def action_names() action_methods end
+ def self.app_loaded!
+ @subclasses.each do |subclass|
+ subclass.constantize._write_layout_method
+ end
+ end
- # :api: plugin
- def self.call(env)
- controller = new
- controller.call(env).to_rack
+ def render_to_body(action = nil, options = {})
+ if action.is_a?(Hash)
+ options, action = action, nil
+ elsif action.is_a?(String) || action.is_a?(Symbol)
+ key = case action = action.to_s
+ when %r{^/} then :file
+ when %r{/} then :template
+ else :action
+ end
+ options.merge! key => action
+ elsif action
+ options.merge! :partial => action
+ end
+
+ if options.key?(:action) && options[:action].to_s.index("/")
+ options[:template] = options.delete(:action)
+ end
+
+ # options = {:template => options.to_s} if options.is_a?(String) || options.is_a?(Symbol)
+ super(options) || " "
end
- # :api: plugin
- def response_body=(body)
- @_response.body = body
+ # Redirects the browser to the target specified in +options+. This parameter can take one of three forms:
+ #
+ # * <tt>Hash</tt> - The URL will be generated by calling url_for with the +options+.
+ # * <tt>Record</tt> - The URL will be generated by calling url_for with the +options+, which will reference a named URL for that record.
+ # * <tt>String</tt> starting with <tt>protocol://</tt> (like <tt>http://</tt>) - Is passed straight through as the target for redirection.
+ # * <tt>String</tt> not containing a protocol - The current protocol and host is prepended to the string.
+ # * <tt>:back</tt> - Back to the page that issued the request. Useful for forms that are triggered from multiple places.
+ # Short-hand for <tt>redirect_to(request.env["HTTP_REFERER"])</tt>
+ #
+ # Examples:
+ # redirect_to :action => "show", :id => 5
+ # redirect_to post
+ # redirect_to "http://www.rubyonrails.org"
+ # redirect_to "/images/screenshot.jpg"
+ # redirect_to articles_url
+ # redirect_to :back
+ #
+ # The redirection happens as a "302 Moved" header unless otherwise specified.
+ #
+ # Examples:
+ # redirect_to post_url(@post), :status=>:found
+ # redirect_to :action=>'atom', :status=>:moved_permanently
+ # redirect_to post_url(@post), :status=>301
+ # redirect_to :action=>'atom', :status=>302
+ #
+ # When using <tt>redirect_to :back</tt>, if there is no referrer,
+ # RedirectBackError will be raised. You may specify some fallback
+ # behavior for this case by rescuing RedirectBackError.
+ def redirect_to(options = {}, response_status = {}) #:doc:
+ raise ActionControllerError.new("Cannot redirect to nil!") if options.nil?
+
+ status = if options.is_a?(Hash) && options.key?(:status)
+ interpret_status(options.delete(:status))
+ elsif response_status.key?(:status)
+ interpret_status(response_status[:status])
+ else
+ 302
+ end
+
+ url = case options
+ # The scheme name consist of a letter followed by any combination of
+ # letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
+ # characters; and is terminated by a colon (":").
+ when %r{^\w[\w\d+.-]*:.*}
+ options
+ when String
+ request.protocol + request.host_with_port + options
+ when :back
+ raise RedirectBackError unless refer = request.headers["Referer"]
+ refer
+ else
+ url_for(options)
+ end
+
+ super(url, status)
end
- # :api: private
- def call(env)
- @_request = ActionDispatch::Request.new(env)
- @_response = ActionDispatch::Response.new
- process(@_request.parameters[:action])
+ def process_action
+ ret = super
+ render if response_body.nil?
+ ret
end
- # :api: private
- def to_rack
- response.to_a
+ def respond_to_action?(action_name)
+ super || view_paths.find_by_parts?(action_name.to_s, {:formats => formats, :locales => [I18n.locale]}, controller_path)
end
end
-end
+end
View
91 actionpack/lib/action_controller/new_base/compatibility.rb
@@ -0,0 +1,91 @@
+module ActionController
+ module Rails2Compatibility
+ extend ActiveSupport::DependencyModule
+
+ # Temporary hax
+ included do
+ ::ActionController::UnknownAction = ::AbstractController::ActionNotFound
+ ::ActionController::DoubleRenderError = ::AbstractController::DoubleRenderError
+
+ cattr_accessor :session_options
+ self.session_options = {}
+
+ cattr_accessor :allow_concurrency
+ self.allow_concurrency = false
+
+ cattr_accessor :param_parsers
+ self.param_parsers = { Mime::MULTIPART_FORM => :multipart_form,
+ Mime::URL_ENCODED_FORM => :url_encoded_form,
+ Mime::XML => :xml_simple,
+ Mime::JSON => :json }
+
+ cattr_accessor :relative_url_root
+ self.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT']
+
+ cattr_accessor :default_charset
+ self.default_charset = "utf-8"
+
+ # cattr_reader :protected_instance_variables
+ cattr_accessor :protected_instance_variables
+ self.protected_instance_variables = %w(@assigns @performed_redirect @performed_render @variables_added @request_origin @url @parent_controller
+ @action_name @before_filter_chain_aborted @action_cache_path @_headers @_params
+ @_flash @_response)
+
+ # Indicates whether or not optimise the generated named
+ # route helper methods
+ cattr_accessor :optimise_named_routes
+ self.optimise_named_routes = true
+
+ cattr_accessor :resources_path_names
+ self.resources_path_names = { :new => 'new', :edit => 'edit' }
+
+ # Controls the resource action separator
+ cattr_accessor :resource_action_separator
+ self.resource_action_separator = "/"
+
+ cattr_accessor :use_accept_header
+ self.use_accept_header = true
+ end
+
+ module ClassMethods
+ def protect_from_forgery() end
+ def consider_all_requests_local() end
+ def rescue_action(env)
+ raise env["action_dispatch.rescue.exception"]
+ end
+ end
+
+ def initialize(*)
+ super
+ @template = _action_view
+ end
+
+ def render_to_body(options)
+ if options.is_a?(Hash) && options.key?(:template)
+ options[:template].sub!(/^\//, '')
+ end
+
+ options[:text] = nil if options[:nothing] == true
+
+ super
+ end
+
+ def respond_to_action?(action_name)
+ if respond_to?(:method_missing) && !respond_to?(:action_missing)
+ self.class.class_eval do
+ private
+ def action_missing(name, *args)
+ method_missing(name.to_sym, *args)
+ end
+ end
+ end
+ super
+ end
+
+ def _layout_for_name(name)
+ name &&= name.sub(%r{^/?layouts/}, '')
+ super
+ end
+
+ end
+end
View
131 actionpack/lib/action_controller/new_base/conditional_get.rb
@@ -0,0 +1,131 @@
+module ActionController
+ module ConditionalGet
+
+ # Sets the etag, last_modified, or both on the response and renders a
+ # "304 Not Modified" response if the request is already fresh.
+ #
+ # Parameters:
+ # * <tt>:etag</tt>
+ # * <tt>:last_modified</tt>
+ # * <tt>:public</tt> By default the Cache-Control header is private, set this to true if you want your application to be cachable by other devices (proxy caches).
+ #
+ # Example:
+ #
+ # def show
+ # @article = Article.find(params[:id])
+ # fresh_when(:etag => @article, :last_modified => @article.created_at.utc, :public => true)
+ # end
+ #
+ # This will render the show template if the request isn't sending a matching etag or
+ # If-Modified-Since header and just a "304 Not Modified" response if there's a match.
+ #
+ def fresh_when(options)
+ options.assert_valid_keys(:etag, :last_modified, :public)
+
+ response.etag = options[:etag] if options[:etag]
+ response.last_modified = options[:last_modified] if options[:last_modified]
+
+ if options[:public]
+ cache_control = response.headers["Cache-Control"].split(",").map {|k| k.strip }
+ cache_control.delete("private")
+ cache_control.delete("no-cache")
+ cache_control << "public"
+ response.headers["Cache-Control"] = cache_control.join(', ')
+ end
+
+ if request.fresh?(response)
+ head :not_modified
+ end
+ end
+
+ # Return a response that has no content (merely headers). The options
+ # argument is interpreted to be a hash of header names and values.
+ # This allows you to easily return a response that consists only of
+ # significant headers:
+ #
+ # head :created, :location => person_path(@person)
+ #
+ # It can also be used to return exceptional conditions:
+ #
+ # return head(:method_not_allowed) unless request.post?
+ # return head(:bad_request) unless valid_request?
+ # render
+ def head(*args)
+ if args.length > 2
+ raise ArgumentError, "too many arguments to head"
+ elsif args.empty?
+ raise ArgumentError, "too few arguments to head"
+ end
+ options = args.extract_options!
+ status = interpret_status(args.shift || options.delete(:status) || :ok)
+
+ options.each do |key, value|
+ headers[key.to_s.dasherize.split(/-/).map { |v| v.capitalize }.join("-")] = value.to_s
+ end
+
+ render :nothing => true, :status => status
+ end
+
+ # Sets the etag and/or last_modified on the response and checks it against
+ # the client request. If the request doesn't match the options provided, the
+ # request is considered stale and should be generated from scratch. Otherwise,
+ # it's fresh and we don't need to generate anything and a reply of "304 Not Modified" is sent.
+ #
+ # Parameters:
+ # * <tt>:etag</tt>
+ # * <tt>:last_modified</tt>
+ # * <tt>:public</tt> By default the Cache-Control header is private, set this to true if you want your application to be cachable by other devices (proxy caches).
+ #
+ # Example:
+ #
+ # def show
+ # @article = Article.find(params[:id])
+ #
+ # if stale?(:etag => @article, :last_modified => @article.created_at.utc)
+ # @statistics = @article.really_expensive_call
+ # respond_to do |format|
+ # # all the supported formats
+ # end
+ # end
+ # end
+ def stale?(options)
+ fresh_when(options)
+ !request.fresh?(response)
+ end
+
+ # Sets a HTTP 1.1 Cache-Control header. Defaults to issuing a "private" instruction, so that
+ # intermediate caches shouldn't cache the response.
+ #