Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge remote branch 'mainstream/master'

Conflicts:
	activerecord/lib/active_record/base.rb
	railties/lib/rails/configuration.rb
	railties/lib/rails/log_subscriber.rb
  • Loading branch information...
commit e68bfaf1fe1a7890a67af6f444281185f507cf9e 2 parents ef6462c + 1684655
@lifo lifo authored
Showing with 4,484 additions and 3,671 deletions.
  1. +3 −3 .gitignore
  2. +7 −2 Gemfile
  3. +1 −0  RAILS_VERSION
  4. +36 −12 Rakefile
  5. +0 −11 actionmailer/Rakefile
  6. +7 −5 actionmailer/actionmailer.gemspec
  7. +1 −0  actionmailer/lib/action_mailer.rb
  8. +58 −25 actionmailer/lib/action_mailer/base.rb
  9. +2 −2 actionmailer/lib/action_mailer/old_api.rb
  10. +1 −1  actionmailer/lib/action_mailer/quoting.rb
  11. +8 −6 actionmailer/lib/action_mailer/railtie.rb
  12. +1 −1  actionmailer/lib/action_mailer/railties/{subscriber.rb → log_subscriber.rb}
  13. +3 −2 actionmailer/lib/action_mailer/version.rb
  14. +4 −1 actionmailer/test/abstract_unit.rb
  15. +62 −21 actionmailer/test/base_test.rb
  16. +9 −5 actionmailer/test/{subscriber_test.rb → log_subscriber_test.rb}
  17. +6 −3 actionmailer/test/old_base/asset_host_test.rb
  18. +8 −2 actionmailer/test/old_base/url_test.rb
  19. +1 −31 actionpack/Rakefile
  20. +7 −5 actionpack/actionpack.gemspec
  21. +4 −2 actionpack/lib/abstract_controller.rb
  22. +13 −5 actionpack/lib/abstract_controller/base.rb
  23. +2 −0  actionpack/lib/abstract_controller/collector.rb
  24. +0 −18 actionpack/lib/abstract_controller/compatibility.rb
  25. +3 −5 actionpack/lib/abstract_controller/helpers.rb
  26. +36 −98 actionpack/lib/abstract_controller/layouts.rb
  27. +0 −49 actionpack/lib/abstract_controller/localized_cache.rb
  28. +2 −2 actionpack/lib/abstract_controller/logger.rb
  29. +58 −154 actionpack/lib/abstract_controller/rendering.rb
  30. +73 −0 actionpack/lib/abstract_controller/view_paths.rb
  31. +1 −2  actionpack/lib/action_controller.rb
  32. +4 −30 actionpack/lib/action_controller/base.rb
  33. +19 −18 actionpack/lib/action_controller/caching.rb
  34. +3 −1 actionpack/lib/action_controller/caching/fragments.rb
  35. +24 −24 actionpack/lib/action_controller/caching/pages.rb
  36. +1 −3 actionpack/lib/action_controller/caching/sweeping.rb
  37. +0 −2  actionpack/lib/action_controller/deprecated.rb
  38. +131 −0 actionpack/lib/action_controller/deprecated/base.rb
  39. +18 −25 actionpack/lib/action_controller/metal.rb
  40. +18 −80 actionpack/lib/action_controller/metal/compatibility.rb
  41. +0 −28 actionpack/lib/action_controller/metal/configuration.rb
  42. +1 −0  actionpack/lib/action_controller/metal/head.rb
  43. +2 −2 actionpack/lib/action_controller/metal/helpers.rb
  44. +4 −6 actionpack/lib/action_controller/metal/hide_actions.rb
  45. +17 −33 actionpack/lib/action_controller/metal/http_authentication.rb
  46. +21 −0 actionpack/lib/action_controller/metal/implicit_render.rb
  47. +1 −1  actionpack/lib/action_controller/metal/instrumentation.rb
  48. +1 −4 actionpack/lib/action_controller/metal/rack_delegation.rb
  49. +1 −0  actionpack/lib/action_controller/metal/redirecting.rb
  50. +1 −1  actionpack/lib/action_controller/metal/renderers.rb
  51. +27 −41 actionpack/lib/action_controller/metal/rendering.rb
  52. +41 −4 actionpack/lib/action_controller/metal/request_forgery_protection.rb
  53. +0 −36 actionpack/lib/action_controller/metal/session_management.rb
  54. +20 −47 actionpack/lib/action_controller/metal/streaming.rb
  55. +0 −1  actionpack/lib/action_controller/metal/testing.rb
  56. +11 −156 actionpack/lib/action_controller/metal/url_for.rb
  57. +2 −1  actionpack/lib/action_controller/middleware.rb
  58. +1 −2  actionpack/lib/action_controller/polymorphic_routes.rb
  59. +60 −10 actionpack/lib/action_controller/railtie.rb
  60. +2 −10 actionpack/lib/action_controller/railties/{subscriber.rb → log_subscriber.rb}
  61. +14 −0 actionpack/lib/action_controller/railties/url_helpers.rb
  62. +20 −1 actionpack/lib/action_controller/record_identifier.rb
  63. +20 −11 actionpack/lib/action_controller/test_case.rb
  64. +0 −76 actionpack/lib/action_controller/url_rewriter.rb
  65. +1 −0  actionpack/lib/action_dispatch.rb
  66. +18 −3 actionpack/lib/action_dispatch/http/cache.rb
  67. +40 −25 actionpack/lib/action_dispatch/http/filter_parameters.rb
  68. +0 −15 actionpack/lib/action_dispatch/http/mime_negotiation.rb
  69. +9 −30 actionpack/lib/action_dispatch/http/request.rb
  70. +34 −15 actionpack/lib/action_dispatch/http/response.rb
  71. +5 −32 actionpack/lib/action_dispatch/http/url.rb
  72. +1 −1  actionpack/lib/action_dispatch/middleware/callbacks.rb
  73. +0 −1  actionpack/lib/action_dispatch/middleware/params_parser.rb
  74. +51 −0 actionpack/lib/action_dispatch/middleware/remote_ip.rb
  75. +5 −8 actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
  76. +6 −2 actionpack/lib/action_dispatch/middleware/stack.rb
  77. +3 −0  actionpack/lib/action_dispatch/railtie.rb
  78. +1 −0  actionpack/lib/action_dispatch/routing.rb
  79. +33 −7 actionpack/lib/action_dispatch/routing/deprecated_mapper.rb
  80. +40 −14 actionpack/lib/action_dispatch/routing/mapper.rb
  81. +2 −2 actionpack/lib/action_dispatch/routing/route.rb
  82. +201 −157 actionpack/lib/action_dispatch/routing/route_set.rb
  83. +139 −0 actionpack/lib/action_dispatch/routing/url_for.rb
  84. +14 −9 actionpack/lib/action_dispatch/testing/assertions/response.rb
  85. +12 −15 actionpack/lib/action_dispatch/testing/assertions/routing.rb
  86. +31 −26 actionpack/lib/action_dispatch/testing/integration.rb
  87. +2 −0  actionpack/lib/action_dispatch/testing/test_process.rb
  88. +4 −3 actionpack/lib/action_pack/version.rb
  89. +9 −6 actionpack/lib/action_view.rb
  90. +28 −66 actionpack/lib/action_view/base.rb
  91. +1 −0  actionpack/lib/action_view/helpers.rb
  92. +11 −9 actionpack/lib/action_view/helpers/active_model_helper.rb
  93. +5 −12 actionpack/lib/action_view/helpers/asset_tag_helper.rb
  94. +2 −2 actionpack/lib/action_view/helpers/atom_feed_helper.rb
  95. +5 −9 actionpack/lib/action_view/helpers/capture_helper.rb
  96. +6 −5 actionpack/lib/action_view/helpers/date_helper.rb
  97. +52 −0 actionpack/lib/action_view/helpers/deprecated_block_helpers.rb
  98. +29 −19 actionpack/lib/action_view/helpers/form_helper.rb
  99. +4 −3 actionpack/lib/action_view/helpers/form_options_helper.rb
  100. +16 −10 actionpack/lib/action_view/helpers/form_tag_helper.rb
  101. +2 −8 actionpack/lib/action_view/helpers/javascript_helper.rb
  102. +42 −44 actionpack/lib/action_view/helpers/number_helper.rb
  103. +17 −11 actionpack/lib/action_view/helpers/prototype_helper.rb
  104. +5 −23 actionpack/lib/action_view/helpers/tag_helper.rb
  105. +5 −4 actionpack/lib/action_view/helpers/translation_helper.rb
  106. +10 −13 actionpack/lib/action_view/helpers/url_helper.rb
  107. +154 −0 actionpack/lib/action_view/lookup_context.rb
  108. +22 −63 actionpack/lib/action_view/paths.rb
  109. +5 −3 actionpack/lib/action_view/railtie.rb
  110. +1 −1  actionpack/lib/action_view/railties/{subscriber.rb → log_subscriber.rb}
  111. +65 −0 actionpack/lib/action_view/render/layouts.rb
  112. +10 −38 actionpack/lib/action_view/render/partials.rb
  113. +46 −69 actionpack/lib/action_view/render/rendering.rb
  114. +16 −16 actionpack/lib/action_view/template.rb
  115. +16 −9 actionpack/lib/action_view/template/handlers/erb.rb
  116. +50 −86 actionpack/lib/action_view/template/resolver.rb
  117. +4 −9 actionpack/lib/action_view/template/text.rb
  118. +8 −1 actionpack/lib/action_view/test_case.rb
  119. +2 −2 actionpack/test/abstract/abstract_controller_test.rb
  120. +85 −33 actionpack/test/abstract/layouts_test.rb
  121. +0 −57 actionpack/test/abstract/localized_cache_test.rb
  122. +1 −60 actionpack/test/abstract/render_test.rb
  123. +81 −24 actionpack/test/abstract_unit.rb
  124. +11 −11 actionpack/test/activerecord/controller_runtime_test.rb
  125. +4 −4 actionpack/test/activerecord/polymorphic_routes_test.rb
  126. +16 −8 actionpack/test/controller/action_pack_assertions_test.rb
  127. +1 −12 actionpack/test/controller/assert_select_test.rb
  128. +57 −2 actionpack/test/controller/base_test.rb
  129. +20 −15 actionpack/test/controller/caching_test.rb
  130. +0 −12 actionpack/test/controller/content_type_test.rb
  131. +1 −1  actionpack/test/controller/cookie_test.rb
  132. +11 −7 actionpack/test/controller/http_digest_authentication_test.rb
  133. +18 −30 actionpack/test/controller/integration_test.rb
  134. +14 −14 actionpack/test/controller/{subscriber_test.rb → log_subscriber_test.rb}
  135. +2 −6 actionpack/test/controller/mime_responds_test.rb
  136. +1 −1  actionpack/test/controller/new_base/render_rjs_test.rb
  137. +1 −0  actionpack/test/controller/record_identifier_test.rb
  138. +9 −9 actionpack/test/controller/redirect_test.rb
  139. +10 −0 actionpack/test/controller/render_json_test.rb
  140. +21 −3 actionpack/test/controller/render_test.rb
  141. +2 −1  actionpack/test/controller/render_xml_test.rb
  142. +2 −2 actionpack/test/controller/rescue_test.rb
  143. +15 −12 actionpack/test/controller/resources_test.rb
  144. +11 −27 actionpack/test/controller/routing_test.rb
  145. +22 −40 actionpack/test/controller/send_file_test.rb
  146. +9 −7 actionpack/test/controller/test_test.rb
  147. +10 −16 actionpack/test/controller/url_for_test.rb
  148. +26 −43 actionpack/test/controller/url_rewriter_test.rb
  149. +3 −0  actionpack/test/controller/view_paths_test.rb
  150. +1 −1  actionpack/test/controller/webservice_test.rb
  151. +36 −0 actionpack/test/dispatch/mount_test.rb
  152. +37 −122 actionpack/test/dispatch/request_test.rb
  153. +8 −16 actionpack/test/dispatch/response_test.rb
  154. +25 −10 actionpack/test/dispatch/routing_test.rb
  155. +38 −0 actionpack/test/dispatch/url_generation_test.rb
  156. +1 −0  actionpack/test/fixtures/hello.html
  157. +2 −0  actionpack/test/fixtures/test/layout_render_file.erb
  158. +17 −16 actionpack/test/lib/controller/fake_models.rb
  159. +11 −6 actionpack/test/lib/fixture_template.rb
  160. +2 −2 actionpack/test/template/active_model_helper_test.rb
  161. +37 −59 actionpack/test/template/asset_tag_helper_test.rb
  162. +4 −4 actionpack/test/template/atom_feed_helper_test.rb
  163. +1 −4 actionpack/test/template/compiled_templates_test.rb
  164. +103 −7 actionpack/test/template/date_helper_test.rb
  165. +82 −0 actionpack/test/template/erb/tag_helper_test.rb
  166. +77 −80 actionpack/test/template/form_helper_test.rb
  167. +11 −11 actionpack/test/template/form_options_helper_test.rb
  168. +18 −25 actionpack/test/template/form_tag_helper_test.rb
  169. +3 −14 actionpack/test/template/javascript_helper_test.rb
  170. +7 −7 actionpack/test/template/{subscriber_test.rb → log_subscriber_test.rb}
  171. +165 −0 actionpack/test/template/lookup_context_test.rb
  172. +6 −2 actionpack/test/template/prototype_helper_test.rb
  173. +1 −0  actionpack/test/template/record_tag_helper_test.rb
  174. +14 −9 actionpack/test/template/render_test.rb
  175. +9 −9 actionpack/test/template/tag_helper_test.rb
  176. +24 −11 actionpack/test/template/test_case_test.rb
  177. +5 −0 actionpack/test/template/translation_helper_test.rb
  178. +51 −45 actionpack/test/template/url_helper_test.rb
  179. +1 −9 activemodel/Rakefile
  180. +6 −4 activemodel/activemodel.gemspec
  181. +1 −1  activemodel/examples/validations.rb
  182. +7 −4 activemodel/lib/active_model/attribute_methods.rb
  183. +35 −10 activemodel/lib/active_model/conversion.rb
  184. +31 −9 activemodel/lib/active_model/lint.rb
  185. +1 −1  activemodel/lib/active_model/naming.rb
  186. +19 −4 activemodel/lib/active_model/validations.rb
  187. +9 −0 activemodel/lib/active_model/validations/with.rb
  188. +18 −0 activemodel/lib/active_model/validator.rb
  189. +3 −2 activemodel/lib/active_model/version.rb
  190. +25 −0 activemodel/test/cases/conversion_test.rb
  191. +3 −0  activemodel/test/cases/helper.rb
  192. +3 −7 activemodel/test/cases/lint_test.rb
  193. +16 −10 activemodel/test/cases/validations/presence_validation_test.rb
  194. +1 −0  activemodel/test/cases/validations/with_validation_test.rb
  195. +27 −0 activemodel/test/cases/validations_test.rb
  196. +7 −1 activemodel/test/models/contact.rb
  197. +0 −15 activerecord/Rakefile
  198. +7 −5 activerecord/activerecord.gemspec
  199. +8 −5 activerecord/lib/active_record.rb
  200. +1 −1  activerecord/lib/active_record/association_preload.rb
  201. +20 −36 activerecord/lib/active_record/associations.rb
  202. +16 −0 activerecord/lib/active_record/attribute_methods/primary_key.rb
  203. +22 −178 activerecord/lib/active_record/base.rb
  204. +1 −1  activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
  205. +7 −4 activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
  206. +1 −0  activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
  207. +165 −0 activerecord/lib/active_record/errors.rb
  208. +2 −2 activerecord/lib/active_record/migration.rb
  209. +3 −3 activerecord/lib/active_record/named_scope.rb
  210. +29 −17 activerecord/lib/active_record/railtie.rb
  211. +5 −5 activerecord/lib/active_record/railties/databases.rake
  212. +1 −1  activerecord/lib/active_record/railties/{subscriber.rb → log_subscriber.rb}
  213. +4 −0 activerecord/lib/active_record/relation.rb
  214. +1 −1  activerecord/lib/active_record/relation/predicate_builder.rb
  215. +14 −14 activerecord/lib/active_record/relation/query_methods.rb
  216. +2 −6 activerecord/lib/active_record/relation/spawn_methods.rb
  217. +3 −2 activerecord/lib/active_record/version.rb
  218. +10 −0 activerecord/test/cases/ar_schema_test.rb
  219. +26 −6 activerecord/test/cases/associations/belongs_to_associations_test.rb
  220. +1 −19 activerecord/test/cases/associations/has_many_associations_test.rb
  221. +2 −2 activerecord/test/cases/associations/has_one_associations_test.rb
  222. +23 −5 activerecord/test/cases/base_test.rb
  223. +2 −2 activerecord/test/cases/calculations_test.rb
  224. +4 −0 activerecord/test/cases/helper.rb
  225. +6 −5 activerecord/test/cases/{subscriber_test.rb → log_subscriber_test.rb}
  226. +10 −0 activerecord/test/cases/method_scoping_test.rb
  227. +14 −0 activerecord/test/cases/pk_test.rb
  228. +3 −6 activerecord/test/models/author.rb
  229. +2 −2 activerecord/test/models/company.rb
  230. +5 −0 activerecord/test/models/developer.rb
  231. +0 −16 activeresource/Rakefile
  232. +7 −5 activeresource/activeresource.gemspec
  233. +2 −2 activeresource/lib/active_resource/railtie.rb
  234. +1 −1  activeresource/lib/active_resource/railties/{subscriber.rb → log_subscriber.rb}
  235. +3 −2 activeresource/lib/active_resource/version.rb
  236. +3 −1 activeresource/test/abstract_unit.rb
  237. +10 −8 activeresource/test/cases/{subscriber_test.rb → log_subscriber_test.rb}
  238. +2 −0  activesupport/CHANGELOG
  239. +0 −12 activesupport/Rakefile
  240. +6 −4 activesupport/activesupport.gemspec
  241. +3 −0  activesupport/lib/active_support.rb
  242. +0 −1  activesupport/lib/active_support/all.rb
  243. +2 −2 activesupport/lib/active_support/callbacks.rb
  244. +0 −1  activesupport/lib/active_support/core_ext/array/conversions.rb
  245. +27 −5 activesupport/lib/active_support/core_ext/class/attribute.rb
  246. +6 −6 activesupport/lib/active_support/core_ext/class/delegating_attributes.rb
  247. +2 −1  activesupport/lib/active_support/core_ext/file/atomic.rb
  248. +5 −0 activesupport/lib/active_support/core_ext/file/path.rb
  249. +1 −1  activesupport/lib/active_support/core_ext/hash/keys.rb
  250. +1 −1  activesupport/lib/active_support/core_ext/object.rb
  251. +0 −13 activesupport/lib/active_support/core_ext/object/metaclass.rb
  252. +13 −0 activesupport/lib/active_support/core_ext/object/singleton_class.rb
  253. +3 −3 activesupport/lib/active_support/core_ext/proc.rb
  254. +1 −0  activesupport/lib/active_support/core_ext/string/conversions.rb
  255. +3 −1 activesupport/lib/active_support/core_ext/string/inflections.rb
  256. +1 −91 activesupport/lib/active_support/core_ext/string/interpolation.rb
  257. +8 −0 activesupport/lib/active_support/core_ext/string/output_safety.rb
  258. +16 −7 activesupport/lib/active_support/dependencies.rb
  259. +5 −0 activesupport/lib/active_support/dependencies/autoload.rb
  260. +9 −9 activesupport/lib/active_support/deprecation/method_wrappers.rb
  261. +2 −1  activesupport/lib/active_support/deprecation/reporting.rb
  262. +2 −1  activesupport/lib/active_support/i18n.rb
  263. +1 −1  activesupport/lib/active_support/inflector/methods.rb
  264. +1 −1  activesupport/lib/active_support/inflector/transliterate.rb
  265. +1 −1  activesupport/lib/active_support/json/decoding.rb
  266. +25 −0 activesupport/lib/active_support/lazy_load_hooks.rb
  267. +1 −1  activesupport/lib/active_support/memoizable.rb
  268. +7 −3 activesupport/lib/active_support/notifications.rb
  269. +18 −4 activesupport/lib/active_support/notifications/fanout.rb
  270. +6 −0 activesupport/lib/active_support/ordered_options.rb
  271. +7 −5 activesupport/lib/active_support/railtie.rb
  272. +1 −0  activesupport/lib/active_support/ruby/shim.rb
  273. +3 −2 activesupport/lib/active_support/version.rb
  274. +3 −4 activesupport/lib/active_support/whiny_nil.rb
  275. +3 −0  activesupport/test/abstract_unit.rb
  276. +0 −1  activesupport/test/callback_inheritance_test.rb
  277. +0 −1  activesupport/test/callbacks_test.rb
  278. +2 −2 activesupport/test/core_ext/array_ext_test.rb
  279. +25 −10 activesupport/test/core_ext/class/attribute_test.rb
  280. +2 −0  activesupport/test/core_ext/class/delegating_attributes_test.rb
  281. +4 −0 activesupport/test/core_ext/file_test.rb
  282. +6 −14 activesupport/test/core_ext/module_test.rb
  283. +4 −7 activesupport/test/core_ext/object_and_class_ext_test.rb
  284. +4 −0 activesupport/test/core_ext/string_ext_test.rb
  285. +6 −3 activesupport/test/inflector_test_cases.rb
  286. +15 −0 activesupport/test/load_paths_test.rb
  287. +43 −4 activesupport/test/notifications_test.rb
  288. +2 −0  activesupport/test/whiny_nil_test.rb
  289. +1 −1  ci/ci_build.rb
  290. +5 −0 load_paths.rb
  291. +0 −14 pushgems.rb
  292. +13 −10 rails.gemspec
  293. +2 −3 rails3b.gemspec
  294. +0 −14 railties/Rakefile
  295. +28 −9 railties/bin/rails
  296. +2 −2 railties/builtin/routes.rb
  297. +1 −1  railties/guides/source/3_0_release_notes.textile
  298. +1 −1  railties/guides/source/configuring.textile
  299. +1 −1  railties/guides/source/security.textile
  300. +1 −1  railties/lib/generators/erb/scaffold/templates/_form.html.erb
Sorry, we could not display the entire diff because too many files (363) changed.
View
6 .gitignore
@@ -1,3 +1,6 @@
+*.gem
+pkg
+.bundle
debug.log
doc/rdoc
activemodel/doc
@@ -16,6 +19,3 @@ railties/doc/guides/html/images
railties/doc/guides/html/stylesheets
railties/guides/output
railties/tmp
-bin
-.bundle
-pkg
View
9 Gemfile
@@ -1,6 +1,7 @@
path File.dirname(__FILE__)
-source 'http://gemcutter.org'
+source 'http://rubygems.org'
+gem "arel", :git => "git://github.com/rails/arel.git"
gem "rails", "3.0.0.beta1"
gem "rake", ">= 0.8.7"
@@ -14,7 +15,7 @@ end
gem "sqlite3-ruby", ">= 1.2.5", :require => 'sqlite3'
group :test do
- gem "pg", ">= 0.8.0"
+ gem "pg", ">= 0.9.0"
gem "mysql", ">= 2.8.1"
end
@@ -22,6 +23,10 @@ end
gem "rack-test", "0.5.3", :require => 'rack/test'
gem "RedCloth", ">= 4.2.2"
+group :documentation do
+ gem 'rdoc', '2.1'
+end
+
if ENV['CI']
gem "nokogiri", ">= 1.4.0"
View
1  RAILS_VERSION
@@ -0,0 +1 @@
+3.0.0.beta1
View
48 Rakefile
@@ -2,23 +2,17 @@ require 'rake'
require 'rake/rdoctask'
require 'rake/gempackagetask'
-env = %(PKG_BUILD="#{ENV['PKG_BUILD']}") if ENV['PKG_BUILD']
-
PROJECTS = %w(activesupport activemodel actionpack actionmailer activeresource activerecord railties)
-Dir["#{File.dirname(__FILE__)}/*/lib/*/version.rb"].each do |version_path|
- require version_path
-end
-
desc 'Run all tests by default'
task :default => %w(test test:isolated)
-%w(test test:isolated rdoc pgem package gem gemspec).each do |task_name|
+%w(test test:isolated rdoc package gem).each do |task_name|
desc "Run #{task_name} task for all projects"
task task_name do
errors = []
PROJECTS.each do |project|
- system(%(cd #{project} && #{env} #{$0} #{task_name})) || errors << project
+ system(%(cd #{project} && #{$0} #{task_name})) || errors << project
end
fail("Errors in #{errors.join(', ')}") unless errors.empty?
end
@@ -27,9 +21,9 @@ end
desc "Smoke-test all projects"
task :smoke do
(PROJECTS - %w(activerecord)).each do |project|
- system %(cd #{project} && #{env} #{$0} test:isolated)
+ system %(cd #{project} && #{$0} test:isolated)
end
- system %(cd activerecord && #{env} #{$0} sqlite3:isolated_test)
+ system %(cd activerecord && #{$0} sqlite3:isolated_test)
end
spec = eval(File.read('rails.gemspec'))
@@ -48,12 +42,14 @@ desc "Release all components to gemcutter."
task :release_projects => :package do
errors = []
PROJECTS.each do |project|
- system(%(cd #{project} && #{env} #{$0} release)) || errors << project
+ system(%(cd #{project} && #{$0} release)) || errors << project
end
fail("Errors in #{errors.join(', ')}") unless errors.empty?
end
+desc "Install gems for all projects."
task :install => :gem do
+ require File.expand_path("../actionpack/lib/action_pack/version", __FILE__)
(PROJECTS - ["railties"]).each do |project|
puts "INSTALLING #{project}"
system("gem install #{project}/pkg/#{project}-#{ActionPack::VERSION::STRING}.gem --no-ri --no-rdoc")
@@ -121,6 +117,34 @@ 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)
+ system %(cd #{project} && #{$0} pdoc)
+ end
+end
+
+task :update_versions do
+ require File.dirname(__FILE__) + "/version"
+
+ File.open("RAILS_VERSION", "w") do |f|
+ f.write Rails::VERSION::STRING + "\n"
+ end
+
+ constants = {
+ "activesupport" => "ActiveSupport",
+ "activemodel" => "ActiveModel",
+ "actionpack" => "ActionPack",
+ "actionmailer" => "ActionMailer",
+ "activeresource" => "ActiveResource",
+ "activerecord" => "ActiveRecord",
+ "railties" => "Rails"
+ }
+
+ version_file = File.read("version.rb")
+
+ PROJECTS.each do |project|
+ Dir["#{project}/lib/*/version.rb"].each do |file|
+ File.open(file, "w") do |f|
+ f.write version_file.gsub(/Rails/, constants[project])
+ end
+ end
end
end
View
11 actionmailer/Rakefile
@@ -4,17 +4,6 @@ require 'rake/testtask'
require 'rake/rdoctask'
require 'rake/packagetask'
require 'rake/gempackagetask'
-require File.join(File.dirname(__FILE__), 'lib', 'action_mailer', 'version')
-
-PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
-PKG_NAME = 'actionmailer'
-PKG_VERSION = ActionMailer::VERSION::STRING + PKG_BUILD
-PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
-
-RELEASE_NAME = "REL #{PKG_VERSION}"
-
-RUBY_FORGE_PROJECT = "actionmailer"
-RUBY_FORGE_USER = "webster132"
desc "Default Task"
task :default => [ :test ]
View
12 actionmailer/actionmailer.gemspec
@@ -1,9 +1,11 @@
+version = File.read(File.expand_path("../../RAILS_VERSION", __FILE__)).strip
+
Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.name = 'actionmailer'
- s.version = '3.0.0.beta1'
- s.summary = 'Email composition, delivery, and recieval framework (part of Rails).'
- s.description = 'Email composition, delivery, and recieval framework (part of Rails).'
+ s.version = version
+ s.summary = 'Email composition, delivery, and receiving framework (part of Rails).'
+ s.description = 'Email on Rails. Compose, deliver, receive, and test emails using the familiar controller/view pattern. First-class support for multipart email and attachments.'
s.required_ruby_version = '>= 1.8.7'
s.author = 'David Heinemeier Hansson'
@@ -17,7 +19,7 @@ Gem::Specification.new do |s|
s.has_rdoc = true
- s.add_dependency('actionpack', '= 3.0.0.beta1')
- s.add_dependency('mail', '~> 2.1.2')
+ s.add_dependency('actionpack', version)
+ s.add_dependency('mail', '~> 2.1.3')
s.add_dependency('text-format', '~> 1.0.0')
end
View
1  actionmailer/lib/action_mailer.rb
@@ -34,6 +34,7 @@
require 'active_support/core_ext/module/attr_internal'
require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/string/inflections'
+require 'active_support/lazy_load_hooks'
module ActionMailer
extend ::ActiveSupport::Autoload
View
83 actionmailer/lib/action_mailer/base.rb
@@ -181,6 +181,18 @@ module ActionMailer #:nodoc:
# and the second being a <tt>application/pdf</tt> with a Base64 encoded copy of the file.pdf book
# with the filename +free_book.pdf+.
#
+ # = Observing and Intercepting Mails
+ #
+ # ActionMailer provides hooks into the Mail observer and interceptor methods. These allow you to
+ # register objects that are called during the mail delivery life cycle.
+ #
+ # An observer object must implement the <tt>:delivered_email(message)</tt> method which will be
+ # called once for every email sent after the email has been sent.
+ #
+ # An interceptor object must implement the <tt>:delivering_email(message)</tt> method which will be
+ # called before the email is sent, allowing you to make modifications to the email before it hits
+ # the delivery agents. Your object should make and needed modifications directly to the passed
+ # in Mail::Message instance.
#
# = Configuration options
#
@@ -255,16 +267,17 @@ class Base < AbstractController::Base
include AbstractController::Logger
include AbstractController::Rendering
- include AbstractController::LocalizedCache
include AbstractController::Layouts
include AbstractController::Helpers
include AbstractController::Translation
- include AbstractController::Compatibility
helper ActionMailer::MailHelper
include ActionMailer::OldApi
include ActionMailer::DeprecatedApi
+
+ delegate :register_observer, :to => Mail
+ delegate :register_interceptor, :to => Mail
private_class_method :new #:nodoc:
@@ -276,6 +289,8 @@ class Base < AbstractController::Base
:parts_order => [ "text/plain", "text/enriched", "text/html" ]
}.freeze
+ ActionMailer.run_base_hooks(self)
+
class << self
def mailer_name
@@ -452,10 +467,27 @@ def attachments
# field for the 'envelope from' value.
#
# If you do not pass a block to the +mail+ method, it will find all templates in the
- # template path that match the method name that it is being called from, it will then
- # create parts for each of these templates intelligently, making educated guesses
- # on correct content type and sequence, and return a fully prepared Mail::Message
- # ready to call <tt>:deliver</tt> on to send.
+ # view paths using by default the mailer name and the method name that it is being
+ # called from, it will then create parts for each of these templates intelligently,
+ # making educated guesses on correct content type and sequence, and return a fully
+ # prepared Mail::Message ready to call <tt>:deliver</tt> on to send.
+ #
+ # For example:
+ #
+ # class Notifier < ActionMailer::Base
+ # default :from => 'no-reply@test.lindsaar.net',
+ #
+ # def welcome
+ # mail(:to => 'mikel@test.lindsaar.net')
+ # end
+ # end
+ #
+ # Will look for all templates at "app/views/notifier" with name "welcome". However, those
+ # can be customized:
+ #
+ # mail(:template_path => 'notifications', :template_name => 'another')
+ #
+ # And now it will look for all templates at "app/views/notifications" with name "another".
#
# If you do pass a block, you can render specific templates of your choice:
#
@@ -493,7 +525,7 @@ def mail(headers={}, &block)
# Merge defaults from class
headers = headers.reverse_merge(self.class.default)
- charset = headers[:charset]
+ charset = headers.delete(:charset)
# Quote fields
headers[:subject] ||= default_i18n_subject
@@ -514,13 +546,11 @@ def mail(headers={}, &block)
end
# Set configure delivery behavior
- wrap_delivery_behavior!(headers[:delivery_method])
+ wrap_delivery_behavior!(headers.delete(:delivery_method))
- # Remove headers already treated and assign all others
- headers.except!(:subject, :to, :from, :cc, :bcc, :reply_to)
- headers.except!(:body, :parts_order, :content_type, :charset, :delivery_method)
+ # Remove any missing configuration header and assign all others
+ headers.except!(:parts_order, :content_type)
headers.each { |k, v| m[k] = v }
-
m
end
@@ -548,12 +578,12 @@ def default_i18n_subject #:nodoc:
# TODO: Move this into Mail
def quote_fields!(headers, charset) #:nodoc:
m = @_message
- m.subject ||= quote_if_necessary(headers[:subject], charset) if headers[:subject]
- m.to ||= quote_address_if_necessary(headers[:to], charset) if headers[:to]
- m.from ||= quote_address_if_necessary(headers[:from], charset) if headers[:from]
- m.cc ||= quote_address_if_necessary(headers[:cc], charset) if headers[:cc]
- m.bcc ||= quote_address_if_necessary(headers[:bcc], charset) if headers[:bcc]
- m.reply_to ||= quote_address_if_necessary(headers[:reply_to], charset) if headers[:reply_to]
+ m.subject ||= quote_if_necessary(headers.delete(:subject), charset) if headers[:subject]
+ m.to ||= quote_address_if_necessary(headers.delete(:to), charset) if headers[:to]
+ m.from ||= quote_address_if_necessary(headers.delete(:from), charset) if headers[:from]
+ m.cc ||= quote_address_if_necessary(headers.delete(:cc), charset) if headers[:cc]
+ m.bcc ||= quote_address_if_necessary(headers.delete(:bcc), charset) if headers[:bcc]
+ m.reply_to ||= quote_address_if_necessary(headers.delete(:reply_to), charset) if headers[:reply_to]
end
def collect_responses_and_parts_order(headers) #:nodoc:
@@ -566,13 +596,16 @@ def collect_responses_and_parts_order(headers) #:nodoc:
responses = collector.responses
elsif headers[:body]
responses << {
- :body => headers[:body],
+ :body => headers.delete(:body),
:content_type => self.class.default[:content_type] || "text/plain"
}
else
- each_template do |template|
+ templates_path = headers.delete(:template_path) || self.class.mailer_name
+ templates_name = headers.delete(:template_name) || action_name
+
+ each_template(templates_path, templates_name) do |template|
responses << {
- :body => render_to_body(:_template => template),
+ :body => render(:_template => template),
:content_type => template.mime_type.to_s
}
end
@@ -581,10 +614,10 @@ def collect_responses_and_parts_order(headers) #:nodoc:
[responses, parts_order]
end
- def each_template(&block) #:nodoc:
- self.class.view_paths.each do |load_paths|
- templates = load_paths.find_all(action_name, {}, self.class.mailer_name)
- templates = templates.uniq_by { |t| t.details[:formats] }
+ def each_template(paths, name, &block) #:nodoc:
+ Array(paths).each do |path|
+ templates = lookup_context.find_all(name, path)
+ templates = templates.uniq_by { |t| t.formats }
unless templates.empty?
templates.each(&block)
View
4 actionmailer/lib/action_mailer/old_api.rb
@@ -206,8 +206,8 @@ def create_parts
if String === @body
@parts.unshift create_inline_part(@body)
elsif @parts.empty? || @parts.all? { |p| p.content_disposition =~ /^attachment/ }
- self.class.view_paths.first.find_all(@template, {}, @mailer_name).each do |template|
- @parts << create_inline_part(render_to_body(:_template => template), template.mime_type)
+ lookup_context.find_all(@template, @mailer_name).each do |template|
+ @parts << create_inline_part(render(:_template => template), template.mime_type)
end
if @parts.size > 1
View
2  actionmailer/lib/action_mailer/quoting.rb
@@ -22,7 +22,7 @@ def quoted_printable_encode(character)
# A quick-and-dirty regexp for determining whether a string contains any
# characters that need escaping.
if !defined?(CHARS_NEEDING_QUOTING)
- CHARS_NEEDING_QUOTING = /[\000-\011\013\014\016-\037\177-\377]/
+ CHARS_NEEDING_QUOTING = Regexp.new('[\000-\011\013\014\016-\037\177-\377]', nil, 'n')
end
# Quote the given text if it contains any "illegal" characters
View
14 actionmailer/lib/action_mailer/railtie.rb
@@ -6,19 +6,21 @@ class Railtie < Rails::Railtie
railtie_name :action_mailer
initializer "action_mailer.url_for", :before => :load_environment_config do |app|
- ActionMailer::Base.send(:include, ActionController::UrlFor) if defined?(ActionController)
+ ActionMailer.base_hook { include app.routes.url_helpers }
end
- require "action_mailer/railties/subscriber"
- subscriber ActionMailer::Railties::Subscriber.new
+ require "action_mailer/railties/log_subscriber"
+ log_subscriber ActionMailer::Railties::LogSubscriber.new
initializer "action_mailer.logger" do
- ActionMailer::Base.logger ||= Rails.logger
+ ActionMailer.base_hook { self.logger ||= Rails.logger }
end
initializer "action_mailer.set_configs" do |app|
- app.config.action_mailer.each do |k,v|
- ActionMailer::Base.send "#{k}=", v
+ ActionMailer.base_hook do
+ app.config.action_mailer.each do |k,v|
+ send "#{k}=", v
+ end
end
end
end
View
2  .../lib/action_mailer/railties/subscriber.rb → .../action_mailer/railties/log_subscriber.rb
@@ -1,6 +1,6 @@
module ActionMailer
module Railties
- class Subscriber < Rails::Subscriber
+ class LogSubscriber < Rails::LogSubscriber
def deliver(event)
recipients = Array(event.payload[:to]).join(', ')
info("\nSent mail to #{recipients} (%1.fms)" % event.duration)
View
5 actionmailer/lib/action_mailer/version.rb
@@ -2,8 +2,9 @@ module ActionMailer
module VERSION #:nodoc:
MAJOR = 3
MINOR = 0
- TINY = "0.beta1"
+ TINY = 0
+ BUILD = "beta1"
- STRING = [MAJOR, MINOR, TINY].join('.')
+ STRING = [MAJOR, MINOR, TINY, BUILD].join('.')
end
end
View
5 actionmailer/test/abstract_unit.rb
@@ -1,5 +1,8 @@
require File.expand_path('../../../load_paths', __FILE__)
+lib = File.expand_path("#{File.dirname(__FILE__)}/../lib")
+$:.unshift(lib) unless $:.include?('lib') || $:.include?(lib)
+
require 'test/unit'
require 'action_mailer'
require 'action_mailer/test_case'
@@ -14,7 +17,7 @@
FIXTURE_LOAD_PATH = File.expand_path('fixtures', File.dirname(__FILE__))
ActionMailer::Base.view_paths = FIXTURE_LOAD_PATH
-class MockSMTP
+class MockSMTP
def self.deliveries
@@deliveries
end
View
83 actionmailer/test/base_test.rb
@@ -14,8 +14,13 @@ def welcome(hash = {})
mail({:subject => "The first email on new API!"}.merge!(hash))
end
- def simple(hash = {})
- mail(hash)
+ def welcome_with_headers(hash = {})
+ headers hash
+ mail
+ end
+
+ def welcome_from_another_path(path)
+ mail(:template_name => "welcome", :template_path => path)
end
def html_only(hash = {})
@@ -25,11 +30,6 @@ def html_only(hash = {})
def plain_text_only(hash = {})
mail(hash)
end
-
- def simple_with_headers(hash = {})
- headers hash
- mail
- end
def attachment_with_content(hash = {})
attachments['invoice.pdf'] = 'This is test File content'
@@ -78,8 +78,12 @@ def custom_block(include_html=false)
format.html{ render "welcome" } if include_html
end
end
-
- def different_template(template_name='')
+
+ def implicit_different_template(template_name='')
+ mail(:template_name => template_name)
+ end
+
+ def explicit_different_template(template_name='')
mail do |format|
format.text { render :template => "#{mailer_name}/#{template_name}" }
format.html { render :template => "#{mailer_name}/#{template_name}" }
@@ -88,13 +92,10 @@ def different_template(template_name='')
def different_layout(layout_name='')
mail do |format|
- format.text {
- render :layout => layout_name
- }
+ format.text { render :layout => layout_name }
format.html { render :layout => layout_name }
end
end
-
end
test "method call to mail does not raise error" do
@@ -154,7 +155,7 @@ def different_layout(layout_name='')
test "can pass random headers in as a hash to mail" do
hash = {'X-Special-Domain-Specific-Header' => "SecretValue",
'In-Reply-To' => '1234@mikel.me.com' }
- mail = BaseMailer.simple(hash)
+ mail = BaseMailer.welcome(hash)
assert_equal('SecretValue', mail['X-Special-Domain-Specific-Header'].decoded)
assert_equal('1234@mikel.me.com', mail['In-Reply-To'].decoded)
end
@@ -162,7 +163,7 @@ def different_layout(layout_name='')
test "can pass random headers in as a hash" do
hash = {'X-Special-Domain-Specific-Header' => "SecretValue",
'In-Reply-To' => '1234@mikel.me.com' }
- mail = BaseMailer.simple_with_headers(hash)
+ mail = BaseMailer.welcome_with_headers(hash)
assert_equal('SecretValue', mail['X-Special-Domain-Specific-Header'].decoded)
assert_equal('1234@mikel.me.com', mail['In-Reply-To'].decoded)
end
@@ -247,9 +248,9 @@ def different_layout(layout_name='')
end
test "uses random default headers from class" do
- with_default BaseMailer, "X-SPAM" => "Not spam" do
- email = BaseMailer.simple
- assert_equal("Not spam", email["X-SPAM"].decoded)
+ with_default BaseMailer, "X-Custom" => "Custom" do
+ email = BaseMailer.welcome
+ assert_equal("Custom", email["X-Custom"].decoded)
end
end
@@ -476,18 +477,58 @@ def different_layout(layout_name='')
end
# Rendering
- test "that you can specify a different template" do
- mail = BaseMailer.different_template('explicit_multipart_templates')
+ test "you can specify a different template for implicit render" do
+ mail = BaseMailer.implicit_different_template('implicit_multipart')
+ assert_equal("HTML Implicit Multipart", mail.html_part.body.decoded)
+ assert_equal("TEXT Implicit Multipart", mail.text_part.body.decoded)
+ end
+
+ test "you can specify a different template for explicit render" do
+ mail = BaseMailer.explicit_different_template('explicit_multipart_templates')
assert_equal("HTML Explicit Multipart Templates", mail.html_part.body.decoded)
assert_equal("TEXT Explicit Multipart Templates", mail.text_part.body.decoded)
end
- test "that you can specify a different layout" do
+ test "you can specify a different layout" do
mail = BaseMailer.different_layout('different_layout')
assert_equal("HTML -- HTML", mail.html_part.body.decoded)
assert_equal("PLAIN -- PLAIN", mail.text_part.body.decoded)
end
+ test "you can specify the template path for implicit lookup" do
+ mail = BaseMailer.welcome_from_another_path('another.path/base_mailer')
+ assert_equal("Welcome from another path", mail.body.encoded)
+
+ mail = BaseMailer.welcome_from_another_path(['unknown/invalid', 'another.path/base_mailer'])
+ assert_equal("Welcome from another path", mail.body.encoded)
+ end
+
+ # Before and After hooks
+
+ class MyObserver
+ def self.delivered_email(mail)
+ end
+ end
+
+ test "you can register an observer to the mail object that gets informed on email delivery" do
+ ActionMailer::Base.register_observer(MyObserver)
+ mail = BaseMailer.welcome
+ MyObserver.expects(:delivered_email).with(mail)
+ mail.deliver
+ end
+
+ class MyInterceptor
+ def self.delivering_email(mail)
+ end
+ end
+
+ test "you can register an interceptor to the mail object that gets passed the mail object before delivery" do
+ ActionMailer::Base.register_interceptor(MyInterceptor)
+ mail = BaseMailer.welcome
+ MyInterceptor.expects(:delivering_email).with(mail)
+ mail.deliver
+ end
+
protected
# Execute the block setting the given values and restoring old values after
View
14 actionmailer/test/subscriber_test.rb → actionmailer/test/log_subscriber_test.rb
@@ -1,10 +1,14 @@
require "abstract_unit"
-require "rails/subscriber/test_helper"
-require "action_mailer/railties/subscriber"
+require "rails/log_subscriber/test_helper"
+require "action_mailer/railties/log_subscriber"
-class AMSubscriberTest < ActionMailer::TestCase
- include Rails::Subscriber::TestHelper
- Rails::Subscriber.add(:action_mailer, ActionMailer::Railties::Subscriber.new)
+class AMLogSubscriberTest < ActionMailer::TestCase
+ include Rails::LogSubscriber::TestHelper
+
+ def setup
+ super
+ Rails::LogSubscriber.add(:action_mailer, ActionMailer::Railties::LogSubscriber.new)
+ end
class TestMailer < ActionMailer::Base
def basic
View
9 actionmailer/test/old_base/asset_host_test.rb
@@ -14,6 +14,10 @@ def setup
set_delivery_method :test
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.deliveries.clear
+ AssetHostMailer.configure do |c|
+ c.asset_host = "http://www.example.com"
+ c.assets_dir = ''
+ end
end
def teardown
@@ -21,13 +25,12 @@ def teardown
end
def test_asset_host_as_string
- ActionController::Base.asset_host = "http://www.example.com"
mail = AssetHostMailer.email_with_asset
assert_equal "<img alt=\"Somelogo\" src=\"http://www.example.com/images/somelogo.png\" />", mail.body.to_s.strip
end
def test_asset_host_as_one_arguement_proc
- ActionController::Base.asset_host = Proc.new { |source|
+ AssetHostMailer.config.asset_host = Proc.new { |source|
if source.starts_with?('/images')
"http://images.example.com"
else
@@ -39,7 +42,7 @@ def test_asset_host_as_one_arguement_proc
end
def test_asset_host_as_two_arguement_proc
- ActionController::Base.asset_host = Proc.new {|source,request|
+ ActionController::Base.config.asset_host = Proc.new {|source,request|
if request && request.ssl?
"https://www.example.com"
else
View
10 actionmailer/test/old_base/url_test.rb
@@ -4,13 +4,19 @@
class WelcomeController < ActionController::Base
end
+AppRoutes = ActionDispatch::Routing::RouteSet.new
+
class ActionMailer::Base
- include ActionController::UrlFor
+ include AppRoutes.url_helpers
end
class TestMailer < ActionMailer::Base
default_url_options[:host] = 'www.basecamphq.com'
+ configure do |c|
+ c.assets_dir = '' # To get the tests to pass
+ end
+
def signed_up_with_url(recipient)
@recipients = recipient
@subject = "[Signed up] Welcome #{recipient}"
@@ -61,7 +67,7 @@ def teardown
def test_signed_up_with_url
TestMailer.delivery_method = :test
- ActionController::Routing::Routes.draw do |map|
+ AppRoutes.draw do |map|
map.connect ':controller/:action/:id'
map.welcome 'welcome', :controller=>"foo", :action=>"bar"
end
View
32 actionpack/Rakefile
@@ -4,17 +4,6 @@ require 'rake/testtask'
require 'rake/rdoctask'
require 'rake/packagetask'
require 'rake/gempackagetask'
-require File.join(File.dirname(__FILE__), 'lib', 'action_pack', 'version')
-
-PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
-PKG_NAME = 'actionpack'
-PKG_VERSION = ActionPack::VERSION::STRING + PKG_BUILD
-PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
-
-RELEASE_NAME = "REL #{PKG_VERSION}"
-
-RUBY_FORGE_PROJECT = "actionpack"
-RUBY_FORGE_USER = "webster132"
desc "Default Task"
task :default => :test
@@ -115,26 +104,7 @@ task :update_js => [ :update_scriptaculous ]
# Publishing ------------------------------------------------------
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
-
-desc "Publish the release files to RubyForge."
-task :release => [ :package ] do
- require 'rubyforge'
- require 'rake/contrib/rubyforgepublisher'
-
- packages = %w( gem tgz zip ).collect{ |ext| "pkg/#{PKG_NAME}-#{PKG_VERSION}.#{ext}" }
-
- rubyforge = RubyForge.new
- rubyforge.login
- rubyforge.add_release(PKG_NAME, PKG_NAME, "REL #{PKG_VERSION}", *packages)
-end
+end
View
12 actionpack/actionpack.gemspec
@@ -1,9 +1,11 @@
+version = File.read(File.expand_path("../../RAILS_VERSION", __FILE__)).strip
+
Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.name = 'actionpack'
- s.version = '3.0.0.beta1'
+ s.version = version
s.summary = 'Web-flow and rendering framework putting the VC in MVC (part of Rails).'
- s.description = 'Web-flow and rendering framework putting the VC in MVC (part of Rails).'
+ s.description = 'Web apps on Rails. Simple, battle-tested conventions for building and testing MVC web applications. Works with any Rack-compatible server.'
s.required_ruby_version = '>= 1.8.7'
s.author = 'David Heinemeier Hansson'
@@ -17,10 +19,10 @@ Gem::Specification.new do |s|
s.has_rdoc = true
- s.add_dependency('activesupport', '= 3.0.0.beta1')
- s.add_dependency('activemodel', '= 3.0.0.beta1')
+ s.add_dependency('activesupport', version)
+ s.add_dependency('activemodel', version)
s.add_dependency('rack', '~> 1.1.0')
s.add_dependency('rack-test', '~> 0.5.0')
- s.add_dependency('rack-mount', '~> 0.4.7')
+ s.add_dependency('rack-mount', '~> 0.6.0')
s.add_dependency('erubis', '~> 2.6.5')
end
View
6 actionpack/lib/abstract_controller.rb
@@ -3,8 +3,11 @@
require 'active_support/ruby/shim'
require 'active_support/dependencies/autoload'
+require 'active_support/core_ext/class/attribute'
require 'active_support/core_ext/module/attr_internal'
require 'active_support/core_ext/module/delegation'
+require 'active_support/core_ext/module/anonymous'
+require 'active_support/i18n'
module AbstractController
extend ActiveSupport::Autoload
@@ -12,11 +15,10 @@ module AbstractController
autoload :Base
autoload :Callbacks
autoload :Collector
- autoload :Compatibility
autoload :Helpers
autoload :Layouts
- autoload :LocalizedCache
autoload :Logger
autoload :Rendering
autoload :Translation
+ autoload :ViewPaths
end
View
18 actionpack/lib/abstract_controller/base.rb
@@ -1,3 +1,5 @@
+require 'active_support/ordered_options'
+
module AbstractController
class Error < StandardError; end
class ActionNotFound < StandardError; end
@@ -5,7 +7,6 @@ class ActionNotFound < StandardError; end
class Base
attr_internal :response_body
attr_internal :action_name
- attr_internal :formats
class << self
attr_reader :abstract
@@ -28,6 +29,14 @@ def descendants
@descendants ||= []
end
+ def config
+ @config ||= ActiveSupport::InheritableOptions.new(superclass < Base ? superclass.config : {})
+ end
+
+ def configure
+ yield config
+ end
+
# A list of all internal methods for a controller. This finds the first
# abstract superclass of a controller, and gets a list of all public
# instance methods on that abstract class. Public instance methods of
@@ -84,15 +93,14 @@ def action_methods
# ==== Returns
# String
def controller_path
- @controller_path ||= name && name.sub(/Controller$/, '').underscore
+ @controller_path ||= name.sub(/Controller$/, '').underscore unless anonymous?
end
end
abstract!
- # Initialize controller with nil formats.
- def initialize #:nodoc:
- @_formats = nil
+ def config
+ @config ||= ActiveSupport::InheritableOptions.new(self.class.config)
end
# Calls the action going through the entire action dispatch stack.
View
2  actionpack/lib/abstract_controller/collector.rb
@@ -1,3 +1,5 @@
+require "action_dispatch/http/mime_type"
+
module AbstractController
module Collector
def self.generate_method_for_mime(mime)
View
18 actionpack/lib/abstract_controller/compatibility.rb
@@ -1,18 +0,0 @@
-module AbstractController
- module Compatibility
- extend ActiveSupport::Concern
-
- def _find_layout(name, details)
- details[:prefix] = nil if name =~ /\blayouts/
- super
- end
-
- # Move this into a "don't run in production" module
- def _default_layout(details, require_layout = false)
- super
- rescue ActionView::MissingTemplate
- _find_layout(_layout({}), {})
- nil
- end
- end
-end
View
8 actionpack/lib/abstract_controller/helpers.rb
@@ -1,6 +1,4 @@
require 'active_support/dependencies'
-require 'active_support/core_ext/class/attribute'
-require 'active_support/core_ext/module/delegation'
module AbstractController
module Helpers
@@ -27,7 +25,7 @@ module ClassMethods
def inherited(klass)
helpers = _helpers
klass._helpers = Module.new { include helpers }
- klass.class_eval { default_helper_module! unless name.blank? }
+ klass.class_eval { default_helper_module! unless anonymous? }
super
end
@@ -99,7 +97,7 @@ def #{meth}(*args, &blk)
def helper(*args, &block)
self._helper_serial = AbstractController::Helpers.next_serial + 1
- _modules_for_helpers(args).each do |mod|
+ modules_for_helpers(args).each do |mod|
add_template_helper(mod)
end
@@ -134,7 +132,7 @@ def add_template_helper(mod)
# ==== Returns
# Array[Module]:: A normalized list of modules for the list of
# helpers provided.
- def _modules_for_helpers(args)
+ def modules_for_helpers(args)
args.flatten.map! do |arg|
case arg
when String, Symbol
View
134 actionpack/lib/abstract_controller/layouts.rb
@@ -1,6 +1,3 @@
-require 'active_support/core_ext/class/attribute'
-require 'active_support/core_ext/module/delegation'
-
module AbstractController
# Layouts reverse the common pattern of including shared headers and footers in many templates to isolate changes in
# repeated setups. The inclusion pattern has pages that look like this:
@@ -173,27 +170,7 @@ module Layouts
module ClassMethods
def inherited(klass)
super
- klass.class_eval do
- _write_layout_method
- @found_layouts = {}
- end
- end
-
- def clear_template_caches!
- @found_layouts.clear if defined? @found_layouts
- super
- end
-
- def cache_layout(details)
- layout = @found_layouts
- key = Thread.current[:format_locale_key]
-
- # Cache nil
- if layout.key?(key)
- return layout[key]
- else
- layout[key] = yield
- end
+ klass._write_layout_method
end
# This module is mixed in if layout conditions are provided. This means
@@ -262,10 +239,10 @@ def _implied_layout_name
def _write_layout_method
case defined?(@_layout) ? @_layout : nil
when String
- self.class_eval %{def _layout(details) #{@_layout.inspect} end}
+ self.class_eval %{def _layout; #{@_layout.inspect} end}
when Symbol
self.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
- def _layout(details)
+ def _layout
#{@_layout}.tap do |layout|
unless layout.is_a?(String) || !layout
raise ArgumentError, "Your layout method :#{@_layout} returned \#{layout}. It " \
@@ -276,21 +253,21 @@ def _layout(details)
ruby_eval
when Proc
define_method :_layout_from_proc, &@_layout
- self.class_eval %{def _layout(details) _layout_from_proc(self) end}
+ self.class_eval %{def _layout; _layout_from_proc(self) end}
when false
- self.class_eval %{def _layout(details) end}
+ self.class_eval %{def _layout; end}
when true
raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil"
when nil
if name
+ _prefix = "layouts" unless _implied_layout_name =~ /\blayouts/
+
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
- def _layout(details)
- self.class.cache_layout(details) do
- if template_exists?("#{_implied_layout_name}", details, :_prefix => "layouts")
- "#{_implied_layout_name}"
- else
- super
- end
+ def _layout
+ if template_exists?("#{_implied_layout_name}", #{_prefix.inspect})
+ "#{_implied_layout_name}"
+ else
+ super
end
end
RUBY
@@ -300,42 +277,20 @@ def _layout(details)
end
end
- def render_to_body(options = {})
- # In the case of a partial with a layout, handle the layout
- # here, and make sure the view does not try to handle it
- layout = options.delete(:layout) if options.key?(:partial)
-
- response = super
+ def _normalize_options(options)
+ super
- # This is a little bit messy. We need to explicitly handle partial
- # layouts here since the core lookup logic is in the view, but
- # we need to determine the layout based on the controller
- #
- # TODO: An easier way to handle this would probably be to override
- # render_template
- if layout
- layout = _layout_for_option(layout, options[:_template].details)
- response = layout.render(view_context, options[:locals] || {}) { response }
+ if _include_layout?(options)
+ layout = options.key?(:layout) ? options.delete(:layout) : :default
+ value = _layout_for_option(layout)
+ options[:layout] = (value =~ /\blayouts/ ? value : "layouts/#{value}") if value
end
-
- response
end
private
# This will be overwritten by _write_layout_method
- def _layout(details) end
-
- # Determine the layout for a given name and details.
- #
- # ==== Parameters
- # name<String>:: The name of the template
- # details<Hash{Symbol => Object}>:: A list of details to restrict
- # the lookup to. By default, layout lookup is limited to the
- # formats specified for the current request.
- def _layout_for_name(name, details)
- name && _find_layout(name, details)
- end
+ def _layout; end
# Determine the layout for a given name and details, taking into account
# the name type.
@@ -345,11 +300,11 @@ def _layout_for_name(name, details)
# details<Hash{Symbol => Object}>:: A list of details to restrict
# the lookup to. By default, layout lookup is limited to the
# formats specified for the current request.
- def _layout_for_option(name, details)
+ def _layout_for_option(name)
case name
- when String then _layout_for_name(name, details)
- when true then _default_layout(details, true)
- when :default then _default_layout(details, false)
+ when String then name
+ when true then _default_layout(true)
+ when :default then _default_layout(false)
when false, nil then nil
else
raise ArgumentError,
@@ -357,29 +312,6 @@ def _layout_for_option(name, details)
end
end
- def _determine_template(options)
- super
-
- return unless (options.keys & [:text, :inline, :partial]).empty? || options.key?(:layout)
- layout = options.key?(:layout) ? options[:layout] : :default
- options[:_layout] = _layout_for_option(layout, options[:_template].details)
- end
-
- # Take in the name and details and find a Template.
- #
- # ==== Parameters
- # name<String>:: The name of the template to retrieve
- # details<Hash>:: A list of details to restrict the search by. This
- # might include details like the format or locale of the template.
- #
- # ==== Returns
- # Template:: A template object matching the name and details
- def _find_layout(name, details)
- # TODO: Make prefix actually part of details in ViewPath#find_by_parts
- prefix = details.key?(:prefix) ? details.delete(:prefix) : "layouts"
- find_template(name, details, :_prefix => prefix)
- end
-
# Returns the default layout for this controller and a given set of details.
# Optionally raises an exception if the layout could not be found.
#
@@ -392,18 +324,24 @@ def _find_layout(name, details)
#
# ==== Returns
# Template:: The template object for the default layout (or nil)
- def _default_layout(details, require_layout = false)
- if require_layout && _action_has_layout? && !_layout(details)
- raise ArgumentError,
- "There was no default layout for #{self.class} in #{view_paths.inspect}"
- end
-
+ def _default_layout(require_layout = false)
begin
- _layout_for_name(_layout(details), details) if _action_has_layout?
+ layout_name = _layout if _action_has_layout?
rescue NameError => e
raise NoMethodError,
"You specified #{@_layout.inspect} as the layout, but no such method was found"
end
+
+ if require_layout && _action_has_layout? && !layout_name
+ raise ArgumentError,
+ "There was no default layout for #{self.class} in #{view_paths.inspect}"
+ end
+
+ layout_name
+ end
+
+ def _include_layout?(options)
+ (options.keys & [:text, :inline, :partial]).empty? || options.key?(:layout)
end
def _action_has_layout?
View
49 actionpack/lib/abstract_controller/localized_cache.rb
@@ -1,49 +0,0 @@
-module AbstractController
- class HashKey
- @hash_keys = Hash.new {|h,k| h[k] = Hash.new {|sh,sk| sh[sk] = {} } }
-
- def self.get(klass, formats, locale)
- @hash_keys[klass][formats][locale] ||= new(klass, formats, locale)
- end
-
- attr_accessor :hash
- def initialize(klass, formats, locale)
- @formats, @locale = formats, locale
- @hash = [formats, locale].hash
- end
-
- alias_method :eql?, :equal?
-
- def inspect
- "#<HashKey -- formats: #{@formats.inspect} locale: #{@locale.inspect}>"
- end
- end
-
- module LocalizedCache
- extend ActiveSupport::Concern
-
- module ClassMethods
- def clear_template_caches!
- ActionView::Partials::PartialRenderer::TEMPLATES.clear
- template_cache.clear
- super
- end
-
- def template_cache
- @template_cache ||= Hash.new {|h,k| h[k] = {} }
- end
- end
-
- def render(*args)
- Thread.current[:format_locale_key] = HashKey.get(self.class, formats, I18n.locale)
- super
- end
-
- private
-
- def with_template_cache(name)
- self.class.template_cache[Thread.current[:format_locale_key]][name] ||= super
- end
-
- end
-end
View
4 actionpack/lib/abstract_controller/logger.rb
@@ -1,5 +1,5 @@
-require 'active_support/core_ext/logger'
-require 'active_support/benchmarkable'
+require "active_support/core_ext/logger"
+require "active_support/benchmarkable"
module AbstractController
module Logger
View
212 actionpack/lib/abstract_controller/rendering.rb
@@ -1,7 +1,4 @@
require "abstract_controller/base"
-require 'active_support/core_ext/class/attribute'
-require 'active_support/core_ext/module/delegation'
-require 'active_support/core_ext/array/wrap'
module AbstractController
class DoubleRenderError < Error
@@ -12,32 +9,47 @@ def initialize(message = nil)
end
end
+ # This is a class to fix I18n global state. Whenever you provide I18n.locale during a request,
+ # it will trigger the lookup_context and consequently expire the cache.
+ # TODO Add some deprecation warnings to remove I18n.locale from controllers
+ class I18nProxy < ::I18n::Config #:nodoc:
+ attr_reader :i18n_config, :lookup_context
+
+ def initialize(i18n_config, lookup_context)
+ @i18n_config, @lookup_context = i18n_config, lookup_context
+ end
+
+ def locale
+ @i18n_config.locale
+ end
+
+ def locale=(value)
+ @i18n_config.locale = value
+ @lookup_context.update_details(:locale => @i18n_config.locale)
+ end
+ end
+
module Rendering
extend ActiveSupport::Concern
+ include AbstractController::ViewPaths
- included do
- class_attribute :_view_paths
- delegate :_view_paths, :to => :'self.class'
- self._view_paths = ActionView::PathSet.new
+ # Overwrite process to setup I18n proxy.
+ def process(*) #:nodoc:
+ old_config, I18n.config = I18n.config, I18nProxy.new(I18n.config, lookup_context)
+ super
+ ensure
+ I18n.config = old_config
end
# An instance of a view class. The default view class is ActionView::Base
#
# The view class must have the following methods:
- # View.for_controller[controller] Create a new ActionView instance for a
- # controller
- # View#render_partial[options]
- # - responsible for setting options[:_template]
- # - Returns String with the rendered partial
- # options<Hash>:: see _render_partial in ActionView::Base
- # View#render_template[template, layout, options, partial]
- # - Returns String with the rendered template
- # template<ActionView::Template>:: The template to render
- # layout<ActionView::Template>:: The layout to render around the template
- # options<Hash>:: See _render_template_with_layout in ActionView::Base
- # partial<Boolean>:: Whether or not the template to render is a partial
+ # View.for_controller[controller]
+ # Create a new ActionView instance for a controller
+ # View#render_template[options]
+ # Returns String with the rendered template
#
- # Override this method in a to change the default behavior.
+ # Override this method in a module to change the default behavior.
def view_context
@_view_context ||= ActionView::Base.for_controller(self)
end
@@ -45,57 +57,29 @@ def view_context
# Mostly abstracts the fact that calling render twice is a DoubleRenderError.
# Delegates render_to_body and sticks the result in self.response_body.
def render(*args, &block)
- options = _normalize_options(*args, &block)
+ options = _normalize_args(*args, &block)
+ _normalize_options(options)
self.response_body = render_to_body(options)
end
# Raw rendering of a template to a Rack-compatible body.
- #
- # ==== Options
- # _partial_object<Object>:: The object that is being rendered. If this
- # exists, we are in the special case of rendering an object as a partial.
- #
# :api: plugin
def render_to_body(options = {})
- # TODO: Refactor so we can just use the normal template logic for this
- if options.key?(:partial)
- _render_partial(options)
- else
- _determine_template(options)
- _render_template(options)
- end
+ _process_options(options)
+ _render_template(options)
end
# Raw rendering of a template to a string. Just convert the results of
# render_to_body into a String.
- #
# :api: plugin
- def render_to_string(*args)
- options = _normalize_options(*args)
+ def render_to_string(options={})
+ _normalize_options(options)
AbstractController::Rendering.body_to_s(render_to_body(options))
end
- # Renders the template from an object.
- #
- # ==== Options
- # _template<ActionView::Template>:: The template to render
- # _layout<ActionView::Template>:: The layout to wrap the template in (optional)
+ # Find and renders a template based on the options given.
def _render_template(options)
- view_context.render_template(options)
- end
-
- # Renders the given partial.
- #
- # ==== Options
- # partial<String|Object>:: The partial name or the object to be rendered
- def _render_partial(options)
- view_context.render_partial(options)
- end
-
- # The list of view paths for this controller. See ActionView::ViewPathSet for
- # more details about writing custom view paths.
- def view_paths
- _view_paths
+ view_context.render_template(options) { |template| _with_template_hook(template) }
end
# The prefix used in render "foo" shortcuts.
@@ -117,122 +101,42 @@ def self.body_to_s(body)
private
- # Normalize options, by converting render "foo" to render :template => "prefix/foo"
- # and render "/foo" to render :file => "/foo".
- def _normalize_options(action=nil, options={})
+ # Normalize options by converting render "foo" to render :action => "foo" and
+ # render "foo/bar" to render :file => "foo/bar".
+ def _normalize_args(action=nil, options={})
case action
+ when NilClass
when Hash
options, action = action, nil
when String, Symbol
action = action.to_s
- case action.index("/")
- when NilClass
- options[:_prefix] = _prefix
- options[:_template_name] = action
- when 0
- options[:file] = action
- else
- options[:template] = action
- end
+ key = action.include?(?/) ? :file : :action
+ options[key] = action
+ else
+ options.merge!(:partial => action)
end
options
end
- # Take in a set of options and determine the template to render
- #
- # ==== Options
- # _template<ActionView::Template>:: If this is provided, the search is over
- # _template_name<#to_s>:: The name of the template to look up. Otherwise,
- # use the current action name.
- # _prefix<String>:: The prefix to look inside of. In a file system, this corresponds
- # to a directory.
- # _partial<TrueClass, FalseClass>:: Whether or not the file to look up is a partial
- def _determine_template(options)
- if options.key?(:text)
- options[:_template] = ActionView::Template::Text.new(options[:text], format_for_text)
- elsif options.key?(:inline)
- handler = ActionView::Template.handler_class_for_extension(options[:type] || "erb")
- template = ActionView::Template.new(options[:inline], "inline template", handler, {})
- options[:_template] = template
- elsif options.key?(:template)
- options[:_template_name] = options[:template]
- elsif options.key?(:file)
- options[:_template_name] = options[:file]
+ def _normalize_options(options)
+ if options[:partial] == true
+ options[:partial] = action_name
end
- name = (options[:_template_name] || options[:action] || action_name).to_s
- options[:_prefix] ||= _prefix if (options.keys & [:partial, :file, :template]).empty?
-
- details = _normalize_details(options)
- options[:_template] ||= with_template_cache(name) do
- find_template(name, details, options)
+ if (options.keys & [:partial, :file, :template]).empty?
+ options[:prefix] ||= _prefix
end
- end
-
- def _normalize_details(options)
- details = { :formats => formats }
- details[:formats] = Array(options[:format]) if options[:format]
- details[:locale] = Array(options[:locale]) if options[:locale]
- details
- end
- def find_template(name, details, options)
- view_paths.find(name, details, options[:_prefix], options[:_partial])
- end
-
- def template_exists?(name, details, options)
- view_paths.exists?(name, details, options[:_prefix], options[:_partial])
- end
-
- def with_template_cache(name)
- yield
+ options[:template] ||= (options[:action] || action_name).to_s
+ options
end
- def format_for_text
- Mime[:text]
+ def _process_options(options)
end
- module ClassMethods
- def clear_template_caches!
- end
-
- # Append a path to the list of view paths for this controller.
- #
- # ==== Parameters
- # path<String, ViewPath>:: If a String is provided, it gets converted into
- # the default view path. You may also provide a custom view path
- # (see ActionView::ViewPathSet for more information)
- def append_view_path(path)
- self.view_paths = view_paths.dup + Array.wrap(path)
- end
-
- # Prepend a path to the list of view paths for this controller.
- #
- # ==== Parameters
- # path<String, ViewPath>:: If a String is provided, it gets converted into
- # the default view path. You may also provide a custom view path
- # (see ActionView::ViewPathSet for more information)
- def prepend_view_path(path)
- clear_template_caches!
- self.view_paths = Array.wrap(path) + view_paths.dup
- end
-
- # A list of all of the default view paths for this controller.
- def view_paths
- _view_paths
- end
-
- # Set the view paths.
- #
- # ==== Parameters
- # paths<ViewPathSet, Object>:: If a ViewPathSet is provided, use that;
- # otherwise, process the parameter into a ViewPathSet.
- def view_paths=(paths)
- clear_template_caches!
- self._view_paths = paths.is_a?(ActionView::PathSet) ? paths : ActionView::Base.process_view_paths(paths)
- _view_paths.freeze
- end
+ def _with_template_hook(template)
+ self.formats = template.formats
end
end
end
View
73 actionpack/lib/abstract_controller/view_paths.rb
@@ -0,0 +1,73 @@
+module AbstractController
+ module ViewPaths
+ extend ActiveSupport::Concern
+
+ included do
+ class_attribute :_view_paths
+ self._view_paths = ActionView::PathSet.new
+ end
+
+ delegate :template_exists?, :view_paths, :formats, :formats=,
+ :locale, :locale=, :to => :lookup_context
+
+ # LookupContext is the object responsible to hold all information required to lookup
+ # templates, i.e. view paths and details. Check ActionView::LookupContext for more
+ # information.
+ def lookup_context
+ @lookup_context ||= ActionView::LookupContext.new(self.class._view_paths, details_for_lookup)
+ end
+
+ def details_for_lookup
+ { }
+ end
+
+ def append_view_path(path)
+ lookup_context.view_paths.push(*path)
+ end
+
+ def prepend_view_path(path)
+ lookup_context.view_paths.unshift(*path)
+ end
+
+ def template_exists?(*args)
+ lookup_context.exists?(*args)
+ end
+
+ module ClassMethods
+ # Append a path to the list of view paths for this controller.
+ #
+ # ==== Parameters
+ # path<String, ViewPath>:: If a String is provided, it gets converted into
+ # the default view path. You may also provide a custom view path
+ # (see ActionView::ViewPathSet for more information)
+ def append_view_path(path)
+ self.view_paths = view_paths.dup + Array(path)
+ end
+
+ # Prepend a path to the list of view paths for this controller.
+ #
+ # ==== Parameters
+ # path<String, ViewPath>:: If a String is provided, it gets converted into
+ # the default view path. You may also provide a custom view path
+ # (see ActionView::ViewPathSet for more information)
+ def prepend_view_path(path)
+ self.view_paths = Array(path) + view_paths.dup
+ end
+
+ # A list of all of the default view paths for this controller.
+ def view_paths
+ _view_paths
+ end
+
+ # Set the view paths.
+ #
+ # ==== Parameters
+ # paths<ViewPathSet, Object>:: If a ViewPathSet is provided, use that;
+ # otherwise, process the parameter into a ViewPathSet.
+ def view_paths=(paths)
+ self._view_paths = paths.is_a?(ActionView::PathSet) ? paths : ActionView::Base.process_view_paths(paths)
+ self._view_paths.freeze
+ end
+ end
+ end
+end
View
3  actionpack/lib/action_controller.rb
@@ -13,13 +13,13 @@ module ActionController
autoload_under "metal" do
autoload :Compatibility
autoload :ConditionalGet
- autoload :Configuration
autoload :Cookies
autoload :Flash
autoload :Head
autoload :Helpers
autoload :HideActions
autoload :HttpAuthentication
+ autoload :ImplicitRender
autoload :Instrumentation
autoload :MimeResponds
autoload :RackDelegation