Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' of git@github.com:lifo/docrails

  • Loading branch information...
commit c480c1db1f302ab28a255c5423326e51d27ec5ed 2 parents 08704c4 + d7bd01f
@FooBarWidget FooBarWidget authored
Showing with 7,625 additions and 4,583 deletions.
  1. +1 −0  .gitignore
  2. +5 −0 actionmailer/CHANGELOG
  3. +6 −6 actionmailer/lib/action_mailer.rb
  4. +38 −7 actionmailer/lib/action_mailer/base.rb
  5. +2 −2 actionmailer/lib/action_mailer/helpers.rb
  6. +1 −0  actionmailer/test/fixtures/auto_layout_mailer/hello.html.erb
  7. +1 −0  actionmailer/test/fixtures/explicit_layout_mailer/logout.html.erb
  8. +1 −0  actionmailer/test/fixtures/explicit_layout_mailer/signup.html.erb
  9. +1 −0  actionmailer/test/fixtures/layouts/auto_layout_mailer.html.erb
  10. +1 −0  actionmailer/test/fixtures/layouts/spam.html.erb
  11. +78 −0 actionmailer/test/mail_layout_test.rb
  12. +3 −9 actionmailer/test/mail_render_test.rb
  13. +52 −0 actionmailer/test/mail_service_test.rb
  14. +32 −0 actionpack/CHANGELOG
  15. +6 −9 actionpack/lib/action_controller.rb
  16. +33 −53 actionpack/lib/action_controller/assertions/selector_assertions.rb
  17. +41 −95 actionpack/lib/action_controller/base.rb
  18. +2 −2 actionpack/lib/action_controller/caching/actions.rb
  19. +3 −3 actionpack/lib/action_controller/caching/sweeping.rb
  20. +3 −3 actionpack/lib/action_controller/cgi_process.rb
  21. +4 −1 actionpack/lib/action_controller/components.rb
  22. +3 −3 actionpack/lib/action_controller/dispatcher.rb
  23. +4 −4 actionpack/lib/action_controller/filters.rb
  24. +2 −2 actionpack/lib/action_controller/helpers.rb
  25. +1 −1  actionpack/lib/action_controller/http_authentication.rb
  26. +37 −49 actionpack/lib/action_controller/integration.rb
  27. +27 −53 actionpack/lib/action_controller/layout.rb
  28. +2 −0  actionpack/lib/action_controller/mime_type.rb
  29. +14 −8 actionpack/lib/action_controller/polymorphic_routes.rb
  30. +66 −36 actionpack/lib/action_controller/rack_process.rb
  31. +6 −4 actionpack/lib/action_controller/request.rb
  32. +1 −4 actionpack/lib/action_controller/rescue.rb
  33. +74 −20 actionpack/lib/action_controller/resources.rb
  34. +44 −11 actionpack/lib/action_controller/response.rb
  35. +7 −5 actionpack/lib/action_controller/routing/builder.rb
  36. +3 −2 actionpack/lib/action_controller/routing/optimisations.rb
  37. +1 −1  actionpack/lib/action_controller/routing/route.rb
  38. +3 −3 actionpack/lib/action_controller/routing/route_set.rb
  39. +3 −3 actionpack/lib/action_controller/routing/segments.rb
  40. +2 −2 actionpack/lib/action_controller/session_management.rb
  41. +2 −2 actionpack/lib/action_controller/templates/rescues/diagnostics.erb
  42. +2 −2 actionpack/lib/action_controller/templates/rescues/template_error.erb
  43. +30 −23 actionpack/lib/action_controller/test_process.rb
  44. +2 −2 actionpack/lib/action_controller/verification.rb
  45. +13 −7 actionpack/lib/action_view.rb
  46. +111 −131 actionpack/lib/action_view/base.rb
  47. +39 −0 actionpack/lib/action_view/helpers.rb
  48. +10 −10 actionpack/lib/action_view/helpers/active_record_helper.rb
  49. +7 −3 actionpack/lib/action_view/helpers/asset_tag_helper.rb
  50. +13 −11 actionpack/lib/action_view/helpers/atom_feed_helper.rb
  51. +10 −4 actionpack/lib/action_view/helpers/prototype_helper.rb
  52. +3 −3 actionpack/lib/action_view/helpers/record_tag_helper.rb
  53. +64 −32 actionpack/lib/action_view/helpers/sanitize_helper.rb
  54. +51 −5 actionpack/lib/action_view/helpers/text_helper.rb
  55. +2 −0  actionpack/lib/action_view/helpers/translation_helper.rb
  56. +0 −53 actionpack/lib/action_view/locale/en-US.rb
  57. +91 −0 actionpack/lib/action_view/locale/en-US.yml
  58. +91 −46 actionpack/lib/action_view/partials.rb
  59. +26 −2 actionpack/lib/action_view/paths.rb
  60. +13 −6 actionpack/lib/action_view/renderable.rb
  61. +13 −3 actionpack/lib/action_view/renderable_partial.rb
  62. +2 −0  actionpack/lib/action_view/template.rb
  63. +1 −1  actionpack/lib/action_view/template_error.rb
  64. +1 −1  actionpack/lib/action_view/template_handlers/builder.rb
  65. +2 −4 actionpack/lib/action_view/test_case.rb
  66. +10 −0 actionpack/test/activerecord/render_partial_with_record_identification_test.rb
  67. +49 −0 actionpack/test/controller/assert_select_test.rb
  68. +4 −4 actionpack/test/controller/base_test.rb
  69. +41 −25 actionpack/test/controller/components_test.rb
  70. +20 −0 actionpack/test/controller/content_type_test.rb
  71. +2 −2 actionpack/test/controller/filter_params_test.rb
  72. +13 −13 actionpack/test/controller/filters_test.rb
  73. +85 −7 actionpack/test/controller/integration_test.rb
  74. +8 −58 actionpack/test/controller/layout_test.rb
  75. +0 −972 actionpack/test/controller/new_render_test.rb
  76. +20 −2 actionpack/test/controller/polymorphic_routes_test.rb
  77. +25 −14 actionpack/test/controller/rack_test.rb
  78. +872 −28 actionpack/test/controller/render_test.rb
  79. +13 −14 actionpack/test/controller/request_test.rb
  80. +122 −25 actionpack/test/controller/resources_test.rb
  81. +29 −0 actionpack/test/controller/routing_test.rb
  82. +5 −0 actionpack/test/controller/test_test.rb
  83. +3 −0  actionpack/test/fixtures/test/_layout_for_block_with_args.html.erb
  84. +1 −0  actionpack/test/fixtures/test/using_layout_around_block_with_args.html.erb
  85. +14 −14 actionpack/test/template/active_record_helper_i18n_test.rb
  86. +32 −5 actionpack/test/template/atom_feed_helper_test.rb
  87. +22 −0 actionpack/test/template/date_helper_i18n_test.rb
  88. +15 −0 actionpack/test/template/prototype_helper_test.rb
  89. +8 −0 actionpack/test/template/record_tag_helper_test.rb
  90. +12 −0 actionpack/test/template/render_test.rb
  91. +3 −3 actionpack/test/template/sanitize_helper_test.rb
  92. +34 −0 actionpack/test/template/text_helper_test.rb
  93. +1 −0  actionpack/test/template/url_helper_test.rb
  94. +3 −3 activemodel/lib/active_model/state_machine/event.rb
  95. +1 −1  activemodel/lib/active_model/validations.rb
  96. +1 −1  activemodel/lib/active_model/validations/exclusion.rb
  97. +1 −1  activemodel/lib/active_model/validations/inclusion.rb
  98. +2 −2 activemodel/lib/active_model/validations/uniqueness.rb
  99. +8 −0 activerecord/CHANGELOG
  100. +8 −14 activerecord/lib/active_record.rb
  101. +2 −6 activerecord/lib/active_record/association_preload.rb
  102. +52 −47 activerecord/lib/active_record/associations.rb
  103. +29 −0 activerecord/lib/active_record/associations/association_collection.rb
  104. +3 −15 activerecord/lib/active_record/associations/association_proxy.rb
  105. +11 −3 activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
  106. +5 −19 activerecord/lib/active_record/associations/has_many_association.rb
  107. +1 −11 activerecord/lib/active_record/associations/has_many_through_association.rb
  108. +2 −2 activerecord/lib/active_record/associations/has_one_association.rb
  109. +4 −0 activerecord/lib/active_record/associations/has_one_through_association.rb
  110. +3 −3 activerecord/lib/active_record/attribute_methods.rb
  111. +137 −120 activerecord/lib/active_record/base.rb
  112. +16 −3 activerecord/lib/active_record/calculations.rb
  113. +9 −10 activerecord/lib/active_record/callbacks.rb
  114. +281 −0 activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
  115. +32 −210 activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb
  116. +29 −14 activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
  117. +9 −4 activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
  118. +2 −6 activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
  119. +24 −2 activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
  120. +14 −0 activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
  121. +12 −7 activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
  122. +4 −1 activerecord/lib/active_record/dirty.rb
  123. +40 −0 activerecord/lib/active_record/dynamic_finder_match.rb
  124. +1 −1  activerecord/lib/active_record/fixtures.rb
  125. +0 −25 activerecord/lib/active_record/locale/en-US.rb
  126. +33 −0 activerecord/lib/active_record/locale/en-US.yml
  127. +36 −11 activerecord/lib/active_record/migration.rb
  128. +8 −4 activerecord/lib/active_record/named_scope.rb
  129. +1 −1  activerecord/lib/active_record/reflection.rb
  130. +1 −1  activerecord/lib/active_record/test_case.rb
  131. +14 −2 activerecord/lib/active_record/transactions.rb
  132. +76 −64 activerecord/lib/active_record/validations.rb
  133. +12 −0 activerecord/test/cases/associations/cascaded_eager_loading_test.rb
  134. +30 −12 activerecord/test/cases/associations/eager_load_nested_include_test.rb
  135. +16 −3 activerecord/test/cases/associations/eager_test.rb
  136. +41 −13 activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
  137. +41 −7 activerecord/test/cases/associations/has_many_associations_test.rb
  138. +24 −0 activerecord/test/cases/associations/has_many_through_associations_test.rb
  139. +10 −0 activerecord/test/cases/associations/has_one_associations_test.rb
  140. +44 −5 activerecord/test/cases/associations/has_one_through_associations_test.rb
  141. +7 −0 activerecord/test/cases/associations/join_model_test.rb
  142. +2 −2 activerecord/test/cases/associations_test.rb
  143. +11 −3 activerecord/test/cases/base_test.rb
  144. +4 −4 activerecord/test/cases/column_definition_test.rb
  145. +1 −1  activerecord/test/cases/defaults_test.rb
  146. +36 −0 activerecord/test/cases/dirty_test.rb
  147. +56 −0 activerecord/test/cases/finder_test.rb
  148. +1 −0  activerecord/test/cases/helper.rb
  149. +41 −0 activerecord/test/cases/i18n_test.rb
  150. +0 −7 activerecord/test/cases/locking_test.rb
  151. +79 −2 activerecord/test/cases/method_scoping_test.rb
  152. +51 −6 activerecord/test/cases/migration_test.rb
  153. +33 −0 activerecord/test/cases/named_scope_test.rb
  154. +87 −0 activerecord/test/cases/pooled_connections_test.rb
  155. +3 −2 activerecord/test/cases/query_cache_test.rb
  156. +4 −0 activerecord/test/cases/reflection_test.rb
  157. +0 −48 activerecord/test/cases/threaded_connections_test.rb
  158. +60 −13 activerecord/test/cases/transactions_test.rb
  159. +417 −149 activerecord/test/cases/validations_i18n_test.rb
  160. +16 −4 activerecord/test/cases/validations_test.rb
  161. +1 −3 activerecord/test/connections/native_mysql/connection.rb
  162. +10 −0 activerecord/test/migrations/broken/100_migration_that_raises_exception.rb
  163. +3 −0  activerecord/test/models/author.rb
  164. +2 −0  activerecord/test/models/developer.rb
  165. +1 −1  activerecord/test/models/project.rb
  166. +2 −2 activerecord/test/schema/mysql_specific_schema.rb
  167. +1 −1  activerecord/test/schema/schema.rb
  168. +4 −0 activeresource/CHANGELOG
  169. +7 −10 activeresource/lib/active_resource.rb
  170. +97 −70 activeresource/lib/active_resource/base.rb
  171. +27 −16 activeresource/lib/active_resource/connection.rb
  172. +12 −11 activeresource/lib/active_resource/custom_methods.rb
  173. +6 −6 activeresource/lib/active_resource/formats/json_format.rb
  174. +9 −9 activeresource/lib/active_resource/formats/xml_format.rb
  175. +1 −1  activeresource/lib/active_resource/http_mock.rb
  176. +8 −8 activeresource/test/authorization_test.rb
  177. +1 −2  activeresource/test/base/custom_methods_test.rb
  178. +2 −2 activeresource/test/base/load_test.rb
  179. +66 −51 activeresource/test/base_test.rb
  180. +1 −1  activeresource/test/connection_test.rb
  181. +23 −11 activeresource/test/format_test.rb
  182. +2 −0  activesupport/CHANGELOG
  183. +3 −7 activesupport/lib/active_support.rb
  184. +12 −7 activesupport/lib/active_support/buffered_logger.rb
  185. +2 −2 activesupport/lib/active_support/cache/file_store.rb
  186. +24 −12 activesupport/lib/active_support/cache/memory_store.rb
  187. +13 −8 activesupport/lib/active_support/callbacks.rb
  188. +0 −127 activesupport/lib/active_support/clean_logger.rb
  189. +5 −5 activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb
  190. +29 −0 activesupport/lib/active_support/core_ext/date/behavior.rb
  191. +6 −0 activesupport/lib/active_support/core_ext/duplicable.rb
  192. +21 −1 activesupport/lib/active_support/core_ext/enumerable.rb
  193. +4 −4 activesupport/lib/active_support/core_ext/kernel/debugger.rb
  194. +128 −1 activesupport/lib/active_support/core_ext/logger.rb
  195. +11 −1 activesupport/lib/active_support/core_ext/module.rb
  196. +71 −67 activesupport/lib/active_support/core_ext/module/aliasing.rb
  197. +79 −75 activesupport/lib/active_support/core_ext/module/introspection.rb
  198. +5 −5 activesupport/lib/active_support/core_ext/module/model_naming.rb
  199. +36 −0 activesupport/lib/active_support/core_ext/module/synchronization.rb
  200. +0 −5 activesupport/lib/active_support/core_ext/object/misc.rb
  201. +2 −2 activesupport/lib/active_support/core_ext/range/blockless_step.rb
  202. +35 −0 activesupport/lib/active_support/core_ext/rexml.rb
  203. +22 −1 activesupport/lib/active_support/core_ext/time.rb
  204. +1 −1  activesupport/lib/active_support/core_ext/time/zones.rb
  205. +7 −3 activesupport/lib/active_support/dependencies.rb
  206. +21 −1 activesupport/lib/active_support/deprecation.rb
  207. +46 −25 activesupport/lib/active_support/inflector.rb
  208. +0 −28 activesupport/lib/active_support/locale/en-US.rb
  209. +31 −0 activesupport/lib/active_support/locale/en-US.yml
  210. +1 −1  activesupport/lib/active_support/option_merger.rb
  211. +197 −0 activesupport/lib/active_support/secure_random.rb
  212. +5 −1 activesupport/lib/active_support/testing/core_ext/test/unit/assertions.rb
  213. +68 −13 activesupport/lib/active_support/testing/performance.rb
  214. +1 −1  activesupport/lib/active_support/time_with_zone.rb
  215. +0 −31 activesupport/lib/active_support/typed_array.rb
  216. +1 −1  activesupport/lib/active_support/vendor.rb
  217. +0 −20 activesupport/lib/active_support/vendor/i18n-0.0.1/MIT-LICENSE
  218. +0 −18 activesupport/lib/active_support/vendor/i18n-0.0.1/README.textile
  219. +0 −24 activesupport/lib/active_support/vendor/i18n-0.0.1/i18n.gemspec
  220. +10 −12 activesupport/lib/active_support/vendor/i18n-0.0.1/{lib → }/i18n.rb
  221. +192 −0 activesupport/lib/active_support/vendor/i18n-0.0.1/i18n/backend/simple.rb
  222. +8 −0 activesupport/lib/active_support/vendor/i18n-0.0.1/{lib → }/i18n/exceptions.rb
  223. +0 −154 activesupport/lib/active_support/vendor/i18n-0.0.1/lib/i18n/backend/simple.rb
  224. +0 −4 activesupport/lib/active_support/vendor/i18n-0.0.1/test/all.rb
  225. +0 −100 activesupport/lib/active_support/vendor/i18n-0.0.1/test/i18n_exceptions_test.rb
  226. +0 −141 activesupport/lib/active_support/vendor/i18n-0.0.1/test/i18n_test.rb
  227. +0 −376 activesupport/lib/active_support/vendor/i18n-0.0.1/test/simple_backend_test.rb
  228. +26 −4 activesupport/test/buffered_logger_test.rb
  229. +30 −0 activesupport/test/caching_test.rb
  230. +4 −4 activesupport/test/callbacks_test.rb
  231. +12 −4 activesupport/test/core_ext/date_ext_test.rb
  232. +1 −1  activesupport/test/core_ext/duplicable_test.rb
  233. +5 −0 activesupport/test/core_ext/enumerable_test.rb
  234. +25 −4 activesupport/test/core_ext/hash_ext_test.rb
  235. +85 −0 activesupport/test/core_ext/module/synchronization_test.rb
  236. +0 −5 activesupport/test/core_ext/object_and_class_ext_test.rb
  237. +4 −0 activesupport/test/core_ext/string_ext_test.rb
  238. +34 −0 activesupport/test/core_ext/time_ext_test.rb
  239. +9 −9 activesupport/test/dependencies_test.rb
  240. +11 −0 activesupport/test/inflector_test.rb
  241. +15 −0 activesupport/test/secure_random_test.rb
  242. +0 −51 activesupport/test/typed_array_test.rb
  243. +116 −0 ci/ci_build.rb
  244. +120 −0 ci/ci_setup_notes.txt
  245. +5 −0 ci/cruise_config.rb
  246. +17 −0 ci/geminstaller.yml
  247. +13 −0 ci/site.css
  248. +72 −0 ci/site_config.rb
  249. +763 −0 railties/doc/guides/routing/routing_outside_in.txt
  250. +1 −1  railties/environments/environment.rb
  251. +4 −1 railties/html/500.html
  252. +1 −1  railties/lib/commands/dbconsole.rb
  253. +1 −3 railties/lib/fcgi_handler.rb
  254. +13 −8 railties/lib/initializer.rb
  255. +1 −0  railties/lib/rails/rack.rb
  256. +28 −0 railties/lib/rails/rack/logger.rb
  257. +4 −0 railties/lib/rails_generator/generated_attribute.rb
  258. +1 −3 railties/lib/rails_generator/generators/applications/app/app_generator.rb
  259. +3 −0  railties/lib/rails_generator/generators/components/model/templates/model.rb
  260. +5 −147 railties/lib/rails_generator/secret_key_generator.rb
  261. +3 −2 railties/lib/tasks/documentation.rake
  262. +5 −0 railties/lib/tasks/framework.rake
  263. +3 −4 railties/lib/tasks/misc.rake
  264. +43 −0 railties/test/error_page_test.rb
  265. +3 −0  railties/test/fixtures/eager/zoo.rb
  266. +2 −0  railties/test/fixtures/eager/zoo/reptile_house.rb
  267. +16 −0 railties/test/generators/rails_model_generator_test.rb
  268. +18 −0 railties/test/initializer_test.rb
  269. +2 −8 railties/test/secret_key_generation_test.rb
View
1  .gitignore
@@ -12,4 +12,5 @@ actionpack/pkg
actionmailer/pkg
activesupport/pkg
railties/pkg
+railties/test/500.html
*.rbc
View
5 actionmailer/CHANGELOG
@@ -1,3 +1,8 @@
+* Add layout functionality to mailers [Pratik]
+
+ Mailer layouts behaves just like controller layouts, except layout names need to
+ have '_mailer' postfix for them to be automatically picked up.
+
*2.1.0 (May 31st, 2008)*
* Fixed that a return-path header would be ignored #7572 [joost]
View
12 actionmailer/lib/action_mailer.rb
@@ -21,13 +21,13 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
-unless defined?(ActionController)
- begin
- $:.unshift "#{File.dirname(__FILE__)}/../../actionpack/lib"
+begin
+ require 'action_controller'
+rescue LoadError
+ actionpack_path = "#{File.dirname(__FILE__)}/../../actionpack/lib"
+ if File.directory?(actionpack_path)
+ $:.unshift actionpack_path
require 'action_controller'
- rescue LoadError
- require 'rubygems'
- gem 'actionpack', '>= 1.12.5'
end
end
View
45 actionmailer/lib/action_mailer/base.rb
@@ -246,7 +246,10 @@ module ActionMailer #:nodoc:
# +implicit_parts_order+.
class Base
include AdvAttrAccessor, PartContainer
- include ActionController::UrlWriter if Object.const_defined?(:ActionController)
+ if Object.const_defined?(:ActionController)
+ include ActionController::UrlWriter
+ include ActionController::Layout
+ end
private_class_method :new #:nodoc:
@@ -362,6 +365,7 @@ def mailer_name=(value)
# The mail object instance referenced by this mailer.
attr_reader :mail
+ attr_reader :template_name, :default_template_name, :action_name
class << self
attr_writer :mailer_name
@@ -374,11 +378,16 @@ def mailer_name
alias_method :controller_name, :mailer_name
alias_method :controller_path, :mailer_name
- def method_missing(method_symbol, *parameters)#:nodoc:
- case method_symbol.id2name
- when /^create_([_a-z]\w*)/ then new($1, *parameters).mail
- when /^deliver_([_a-z]\w*)/ then new($1, *parameters).deliver!
- when "new" then nil
+ def respond_to?(method_symbol, include_private = false) #:nodoc:
+ matches_dynamic_method?(method_symbol) || super
+ end
+
+ def method_missing(method_symbol, *parameters) #:nodoc:
+ match = matches_dynamic_method?(method_symbol)
+ case match[1]
+ when 'create' then new(match[2], *parameters).mail
+ when 'deliver' then new(match[2], *parameters).deliver!
+ when 'new' then nil
else super
end
end
@@ -424,6 +433,12 @@ def template_root
def template_root=(root)
self.view_paths = ActionView::Base.process_view_paths(root)
end
+
+ private
+ def matches_dynamic_method?(method_name) #:nodoc:
+ method_name = method_name.to_s
+ /(create|deliver)_([_a-z]\w*)/.match(method_name) || /^(new)$/.match(method_name)
+ end
end
# Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer
@@ -519,6 +534,7 @@ def initialize_defaults(method_name)
@content_type ||= @@default_content_type.dup
@implicit_parts_order ||= @@default_implicit_parts_order.dup
@template ||= method_name
+ @default_template_name = @action_name = @template
@mailer_name ||= self.class.name.underscore
@parts ||= []
@headers ||= {}
@@ -535,7 +551,22 @@ def render(opts)
if opts[:file] && (opts[:file] !~ /\// && !opts[:file].respond_to?(:render))
opts[:file] = "#{mailer_name}/#{opts[:file]}"
end
- initialize_template_class(body).render(opts)
+
+ begin
+ old_template, @template = @template, initialize_template_class(body)
+ layout = respond_to?(:pick_layout, true) ? pick_layout(opts) : false
+ @template.render(opts.merge(:layout => layout))
+ ensure
+ @template = old_template
+ end
+ end
+
+ def default_template_format
+ :html
+ end
+
+ def candidate_for_layout?(options)
+ !@template.send(:_exempt_from_layout?, default_template_name)
end
def template_root
View
4 actionmailer/lib/action_mailer/helpers.rb
@@ -72,7 +72,7 @@ def helper_method(*methods)
methods.flatten.each do |method|
master_helper_module.module_eval <<-end_eval
def #{method}(*args, &block)
- controller.send!(%(#{method}), *args, &block)
+ controller.__send__(%(#{method}), *args, &block)
end
end_eval
end
@@ -92,7 +92,7 @@ def inherited_with_helper(child)
inherited_without_helper(child)
begin
child.master_helper_module = Module.new
- child.master_helper_module.send! :include, master_helper_module
+ child.master_helper_module.__send__(:include, master_helper_module)
child.helper child.name.to_s.underscore
rescue MissingSourceFile => e
raise unless e.is_missing?("helpers/#{child.name.to_s.underscore}_helper")
View
1  actionmailer/test/fixtures/auto_layout_mailer/hello.html.erb
@@ -0,0 +1 @@
+Inside
View
1  actionmailer/test/fixtures/explicit_layout_mailer/logout.html.erb
@@ -0,0 +1 @@
+You logged out
View
1  actionmailer/test/fixtures/explicit_layout_mailer/signup.html.erb
@@ -0,0 +1 @@
+We do not spam
View
1  actionmailer/test/fixtures/layouts/auto_layout_mailer.html.erb
@@ -0,0 +1 @@
+Hello from layout <%= yield %>
View
1  actionmailer/test/fixtures/layouts/spam.html.erb
@@ -0,0 +1 @@
+Spammer layout <%= yield %>
View
78 actionmailer/test/mail_layout_test.rb
@@ -0,0 +1,78 @@
+require 'abstract_unit'
+
+class AutoLayoutMailer < ActionMailer::Base
+ def hello(recipient)
+ recipients recipient
+ subject "You have a mail"
+ from "tester@example.com"
+ end
+
+ def spam(recipient)
+ recipients recipient
+ subject "You have a mail"
+ from "tester@example.com"
+ body render(:inline => "Hello, <%= @world %>", :layout => 'spam', :body => { :world => "Earth" })
+ end
+
+ def nolayout(recipient)
+ recipients recipient
+ subject "You have a mail"
+ from "tester@example.com"
+ body render(:inline => "Hello, <%= @world %>", :layout => false, :body => { :world => "Earth" })
+ end
+end
+
+class ExplicitLayoutMailer < ActionMailer::Base
+ layout 'spam', :except => [:logout]
+
+ def signup(recipient)
+ recipients recipient
+ subject "You have a mail"
+ from "tester@example.com"
+ end
+
+ def logout(recipient)
+ recipients recipient
+ subject "You have a mail"
+ from "tester@example.com"
+ end
+end
+
+class LayoutMailerTest < Test::Unit::TestCase
+ def setup
+ set_delivery_method :test
+ ActionMailer::Base.perform_deliveries = true
+ ActionMailer::Base.deliveries = []
+
+ @recipient = 'test@localhost'
+ end
+
+ def teardown
+ restore_delivery_method
+ end
+
+ def test_should_pickup_default_layout
+ mail = AutoLayoutMailer.create_hello(@recipient)
+ assert_equal "Hello from layout Inside", mail.body.strip
+ end
+
+ def test_should_pickup_layout_given_to_render
+ mail = AutoLayoutMailer.create_spam(@recipient)
+ assert_equal "Spammer layout Hello, Earth", mail.body.strip
+ end
+
+ def test_should_respect_layout_false
+ mail = AutoLayoutMailer.create_nolayout(@recipient)
+ assert_equal "Hello, Earth", mail.body.strip
+ end
+
+ def test_explicit_class_layout
+ mail = ExplicitLayoutMailer.create_signup(@recipient)
+ assert_equal "Spammer layout We do not spam", mail.body.strip
+ end
+
+ def test_explicit_layout_exceptions
+ mail = ExplicitLayoutMailer.create_logout(@recipient)
+ assert_equal "You logged out", mail.body.strip
+ end
+end
View
12 actionmailer/test/mail_render_test.rb
@@ -20,13 +20,13 @@ def rxml_template(recipient)
subject "rendering rxml template"
from "tester@example.com"
end
-
+
def included_subtemplate(recipient)
recipients recipient
subject "Including another template in the one being rendered"
from "tester@example.com"
end
-
+
def included_old_subtemplate(recipient)
recipients recipient
subject "Including another template in the one being rendered"
@@ -83,17 +83,11 @@ def test_rxml_template
mail = RenderMailer.deliver_rxml_template(@recipient)
assert_equal "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<test/>", mail.body.strip
end
-
+
def test_included_subtemplate
mail = RenderMailer.deliver_included_subtemplate(@recipient)
assert_equal "Hey Ho, let's go!", mail.body.strip
end
-
- def test_deprecated_old_subtemplate
- assert_raises ActionView::ActionViewError do
- RenderMailer.deliver_included_old_subtemplate(@recipient)
- end
- end
end
class FirstSecondHelperTest < Test::Unit::TestCase
View
52 actionmailer/test/mail_service_test.rb
@@ -968,3 +968,55 @@ def test_send_method
end
end
end
+
+class RespondToTest < Test::Unit::TestCase
+ class RespondToMailer < ActionMailer::Base; end
+
+ def setup
+ set_delivery_method :test
+ end
+
+ def teardown
+ restore_delivery_method
+ end
+
+ def test_should_respond_to_new
+ assert RespondToMailer.respond_to?(:new)
+ end
+
+ def test_should_respond_to_create_with_template_suffix
+ assert RespondToMailer.respond_to?(:create_any_old_template)
+ end
+
+ def test_should_respond_to_deliver_with_template_suffix
+ assert RespondToMailer.respond_to?(:deliver_any_old_template)
+ end
+
+ def test_should_not_respond_to_new_with_template_suffix
+ assert !RespondToMailer.respond_to?(:new_any_old_template)
+ end
+
+ def test_should_not_respond_to_create_with_template_suffix_unless_it_is_separated_by_an_underscore
+ assert !RespondToMailer.respond_to?(:createany_old_template)
+ end
+
+ def test_should_not_respond_to_deliver_with_template_suffix_unless_it_is_separated_by_an_underscore
+ assert !RespondToMailer.respond_to?(:deliverany_old_template)
+ end
+
+ def test_should_not_respond_to_create_with_template_suffix_if_it_begins_with_a_uppercase_letter
+ assert !RespondToMailer.respond_to?(:create_Any_old_template)
+ end
+
+ def test_should_not_respond_to_deliver_with_template_suffix_if_it_begins_with_a_uppercase_letter
+ assert !RespondToMailer.respond_to?(:deliver_Any_old_template)
+ end
+
+ def test_should_not_respond_to_create_with_template_suffix_if_it_begins_with_a_digit
+ assert !RespondToMailer.respond_to?(:create_1_template)
+ end
+
+ def test_should_not_respond_to_deliver_with_template_suffix_if_it_begins_with_a_digit
+ assert !RespondToMailer.respond_to?(:deliver_1_template)
+ end
+end
View
32 actionpack/CHANGELOG
@@ -1,5 +1,37 @@
*Edge*
+* Add support for shallow nesting of routes. #838 [S. Brent Faulkner]
+
+ Example :
+
+ map.resources :users, :shallow => true do |user|
+ user.resources :posts
+ end
+
+ - GET /users/1/posts (maps to PostsController#index action as usual)
+ named route "user_posts" is added as usual.
+
+ - GET /posts/2 (maps to PostsController#show action as if it were not nested)
+ Additionally, named route "post" is added too.
+
+* Added button_to_remote helper. #3641 [Donald Piret, Tarmo Tänav]
+
+* Deprecate render_component. Please use render_component plugin from http://github.com/rails/render_component/tree/master [Pratik]
+
+* Routes may be restricted to lists of HTTP methods instead of a single method or :any. #407 [Brennan Dunn, Gaius Centus Novus]
+ map.resource :posts, :collection => { :search => [:get, :post] }
+ map.session 'session', :requirements => { :method => [:get, :post, :delete] }
+
+* Deprecated implicit local assignments when rendering partials [Josh Peek]
+
+* Introduce current_cycle helper method to return the current value without bumping the cycle. #417 [Ken Collins]
+
+* Allow polymorphic_url helper to take url options. #880 [Tarmo Tänav]
+
+* Switched integration test runner to use Rack processor instead of CGI [Josh Peek]
+
+* Made AbstractRequest.if_modified_sense return nil if the header could not be parsed [Jamis Buck]
+
* Added back ActionController::Base.allow_concurrency flag [Josh Peek]
* AbstractRequest.relative_url_root is no longer automatically configured by a HTTP header. It can now be set in your configuration environment with config.action_controller.relative_url_root [Josh Peek]
View
15 actionpack/lib/action_controller.rb
@@ -21,16 +21,13 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
-$:.unshift(File.dirname(__FILE__)) unless
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
-
-unless defined?(ActiveSupport)
- begin
- $:.unshift "#{File.dirname(__FILE__)}/../../activesupport/lib"
+begin
+ require 'active_support'
+rescue LoadError
+ activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
+ if File.directory?(activesupport_path)
+ $:.unshift activesupport_path
require 'active_support'
- rescue LoadError
- require 'rubygems'
- gem 'activesupport'
end
end
View
86 actionpack/lib/action_controller/assertions/selector_assertions.rb
@@ -396,54 +396,31 @@ def count_description(min, max) #:nodoc:
# # The same, but shorter.
# assert_select "ol>li", 4
def assert_select_rjs(*args, &block)
- rjs_type = nil
- arg = args.shift
+ rjs_type = args.first.is_a?(Symbol) ? args.shift : nil
+ id = args.first.is_a?(String) ? args.shift : nil
# If the first argument is a symbol, it's the type of RJS statement we're looking
# for (update, replace, insertion, etc). Otherwise, we're looking for just about
# any RJS statement.
- if arg.is_a?(Symbol)
- rjs_type = arg
-
+ if rjs_type
if rjs_type == :insert
- arg = args.shift
- position = arg
- insertion = "insert_#{arg}".to_sym
- raise ArgumentError, "Unknown RJS insertion type #{arg}" unless RJS_STATEMENTS[insertion]
+ position = args.shift
+ insertion = "insert_#{position}".to_sym
+ raise ArgumentError, "Unknown RJS insertion type #{position}" unless RJS_STATEMENTS[insertion]
statement = "(#{RJS_STATEMENTS[insertion]})"
else
raise ArgumentError, "Unknown RJS statement type #{rjs_type}" unless RJS_STATEMENTS[rjs_type]
statement = "(#{RJS_STATEMENTS[rjs_type]})"
end
- arg = args.shift
else
statement = "#{RJS_STATEMENTS[:any]}"
end
- position ||= Regexp.new(RJS_INSERTIONS.join('|'))
# Next argument we're looking for is the element identifier. If missing, we pick
- # any element.
- if arg.is_a?(String)
- id = Regexp.quote(arg)
- arg = args.shift
- else
- id = "[^\"]*"
- end
-
- pattern =
- case rjs_type
- when :chained_replace, :chained_replace_html
- Regexp.new("\\$\\(\"#{id}\"\\)#{statement}\\(#{RJS_PATTERN_HTML}\\)", Regexp::MULTILINE)
- when :remove, :show, :hide, :toggle
- Regexp.new("#{statement}\\(\"#{id}\"\\)")
- when :replace, :replace_html
- Regexp.new("#{statement}\\(\"#{id}\", #{RJS_PATTERN_HTML}\\)")
- when :insert, :insert_html
- Regexp.new("Element.insert\\(\\\"#{id}\\\", \\{ #{position}: #{RJS_PATTERN_HTML} \\}\\);")
- else
- Regexp.union(Regexp.new("#{statement}\\(\"#{id}\", #{RJS_PATTERN_HTML}\\)"),
- Regexp.new("Element.insert\\(\\\"#{id}\\\", \\{ #{position}: #{RJS_PATTERN_HTML} \\}\\);"))
- end
+ # any element, otherwise we replace it in the statement.
+ pattern = Regexp.new(
+ id ? statement.gsub(RJS_ANY_ID, "\"#{id}\"") : statement
+ )
# Duplicate the body since the next step involves destroying it.
matches = nil
@@ -472,7 +449,13 @@ def assert_select_rjs(*args, &block)
matches
else
# RJS statement not found.
- flunk args.shift || "No RJS statement that replaces or inserts HTML content."
+ case rjs_type
+ when :remove, :show, :hide, :toggle
+ flunk_message = "No RJS statement that #{rjs_type.to_s}s '#{id}' was rendered."
+ else
+ flunk_message = "No RJS statement that replaces or inserts HTML content."
+ end
+ flunk args.shift || flunk_message
end
end
@@ -582,26 +565,23 @@ def assert_select_email(&block)
protected
unless const_defined?(:RJS_STATEMENTS)
- RJS_STATEMENTS = {
- :replace => /Element\.replace/,
- :replace_html => /Element\.update/,
- :chained_replace => /\.replace/,
- :chained_replace_html => /\.update/,
- :remove => /Element\.remove/,
- :show => /Element\.show/,
- :hide => /Element\.hide/,
- :toggle => /Element\.toggle/
+ RJS_PATTERN_HTML = "\"((\\\\\"|[^\"])*)\""
+ RJS_ANY_ID = "\"([^\"])*\""
+ RJS_STATEMENTS = {
+ :chained_replace => "\\$\\(#{RJS_ANY_ID}\\)\\.replace\\(#{RJS_PATTERN_HTML}\\)",
+ :chained_replace_html => "\\$\\(#{RJS_ANY_ID}\\)\\.update\\(#{RJS_PATTERN_HTML}\\)",
+ :replace_html => "Element\\.update\\(#{RJS_ANY_ID}, #{RJS_PATTERN_HTML}\\)",
+ :replace => "Element\\.replace\\(#{RJS_ANY_ID}, #{RJS_PATTERN_HTML}\\)"
}
- RJS_STATEMENTS[:any] = Regexp.new("(#{RJS_STATEMENTS.values.join('|')})")
- RJS_PATTERN_HTML = /"((\\"|[^"])*)"/
- RJS_INSERTIONS = [:top, :bottom, :before, :after]
+ [:remove, :show, :hide, :toggle].each do |action|
+ RJS_STATEMENTS[action] = "Element\\.#{action}\\(#{RJS_ANY_ID}\\)"
+ end
+ RJS_INSERTIONS = ["top", "bottom", "before", "after"]
RJS_INSERTIONS.each do |insertion|
- RJS_STATEMENTS["insert_#{insertion}".to_sym] = /Element.insert\(\"([^\"]*)\", \{ #{insertion.to_s.downcase}: #{RJS_PATTERN_HTML} \}\);/
+ RJS_STATEMENTS["insert_#{insertion}".to_sym] = "Element.insert\\(#{RJS_ANY_ID}, \\{ #{insertion}: #{RJS_PATTERN_HTML} \\}\\)"
end
- RJS_STATEMENTS[:insert_html] = Regexp.new(RJS_INSERTIONS.collect do |insertion|
- /Element.insert\(\"([^\"]*)\", \{ #{insertion.to_s.downcase}: #{RJS_PATTERN_HTML} \}\);/
- end.join('|'))
- RJS_PATTERN_EVERYTHING = Regexp.new("#{RJS_STATEMENTS[:any]}\\(\"([^\"]*)\", #{RJS_PATTERN_HTML}\\)", Regexp::MULTILINE)
+ RJS_STATEMENTS[:insert_html] = "Element.insert\\(#{RJS_ANY_ID}, \\{ (#{RJS_INSERTIONS.join('|')}): #{RJS_PATTERN_HTML} \\}\\)"
+ RJS_STATEMENTS[:any] = Regexp.new("(#{RJS_STATEMENTS.values.join('|')})")
RJS_PATTERN_UNICODE_ESCAPED_CHAR = /\\u([0-9a-zA-Z]{4})/
end
@@ -615,8 +595,8 @@ def response_from_page_or_rjs()
root = HTML::Node.new(nil)
while true
- next if body.sub!(RJS_PATTERN_EVERYTHING) do |match|
- html = unescape_rjs($3)
+ next if body.sub!(RJS_STATEMENTS[:any]) do |match|
+ html = unescape_rjs(match)
matches = HTML::Document.new(html).root.children.select { |n| n.tag? }
root.children.concat matches
""
View
136 actionpack/lib/action_controller/base.rb
@@ -260,10 +260,11 @@ class Base
include StatusCodes
+ cattr_reader :protected_instance_variables
# Controller specific instance variables which will not be accessible inside views.
- @@protected_view_variables = %w(@assigns @performed_redirect @performed_render @variables_added @request_origin @url @parent_controller
- @action_name @before_filter_chain_aborted @action_cache_path @_session @_cookies @_headers @_params
- @_flash @_response)
+ @@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 @_session @_cookies @_headers @_params
+ @_flash @_response)
# Prepends all the URL-generating helpers from AssetHelper. This makes it possible to easily move javascripts, stylesheets,
# and images to a dedicated asset server away from the main web server. Example:
@@ -393,16 +394,9 @@ def self.relative_url_root
# directive. Values should always be specified as strings.
attr_internal :headers
- # Holds the hash of variables that are passed on to the template class to be made available to the view. This hash
- # is generated by taking a snapshot of all the instance variables in the current scope just before a template is rendered.
- attr_accessor :assigns
-
# Returns the name of the action this controller is processing.
attr_accessor :action_name
- # Templates that are exempt from layouts
- @@exempt_from_layout = Set.new([/\.rjs$/])
-
class << self
# Factory for the standard create, process loop where the controller is discarded after processing.
def process(request, response) #:nodoc:
@@ -520,13 +514,7 @@ def filter_parameter_logging(*filter_words, &block)
protected :filter_parameters
end
- # Don't render layouts for templates with the given extensions.
- def exempt_from_layout(*extensions)
- regexps = extensions.collect do |extension|
- extension.is_a?(Regexp) ? extension : /\.#{Regexp.escape(extension.to_s)}$/
- end
- @@exempt_from_layout.merge regexps
- end
+ delegate :exempt_from_layout, :to => 'ActionView::Base'
end
public
@@ -538,7 +526,6 @@ def process(request, response, method = :perform_action, *arguments) #:nodoc:
assign_shortcuts(request, response)
initialize_current_url
assign_names
- forget_variables_added_to_assigns
log_processing
@@ -548,13 +535,16 @@ def process(request, response, method = :perform_action, *arguments) #:nodoc:
@@guard.synchronize { send(method, *arguments) }
end
- assign_default_content_type_and_charset
- response.prepare! unless component_request?
- response
+ send_response
ensure
process_cleanup
end
+ def send_response
+ response.prepare! unless component_request?
+ response
+ end
+
# Returns a URL that has been rewritten according to the options hash and the defined Routes.
# (For doing a complete redirect, use redirect_to).
#
@@ -781,9 +771,6 @@ def append_view_path(path)
# render :file => "/path/to/some/template.erb", :layout => true, :status => 404
# render :file => "c:/path/to/some/template.erb", :layout => true, :status => 404
#
- # # Renders a template relative to the template root and chooses the proper file extension
- # render :file => "some/template", :use_full_path => true
- #
# === Rendering text
#
# Rendering of text is usually used for tests or for rendering prepared content, such as a cache. By default, text
@@ -863,7 +850,7 @@ def render(options = nil, extra_options = {}, &block) #:doc:
raise DoubleRenderError, "Can only render or redirect once per action" if performed?
if options.nil?
- return render_for_file(default_template_name, nil, true)
+ return render(:file => default_template_name, :layout => true)
elsif !extra_options.is_a?(Hash)
raise RenderError, "You called render with invalid options : #{options.inspect}, #{extra_options.inspect}"
else
@@ -874,6 +861,9 @@ def render(options = nil, extra_options = {}, &block) #:doc:
end
end
+ response.layout = layout = pick_layout(options)
+ logger.info("Rendering template within #{layout}") if logger && layout
+
if content_type = options[:content_type]
response.content_type = content_type.to_s
end
@@ -883,26 +873,21 @@ def render(options = nil, extra_options = {}, &block) #:doc:
end
if options.has_key?(:text)
- render_for_text(options[:text], options[:status])
+ text = layout ? @template.render(options.merge(:text => options[:text], :layout => layout)) : options[:text]
+ render_for_text(text, options[:status])
else
if file = options[:file]
- render_for_file(file, options[:status], nil, options[:locals] || {})
+ render_for_file(file, options[:status], layout, options[:locals] || {})
elsif template = options[:template]
- render_for_file(template, options[:status], true, options[:locals] || {})
+ render_for_file(template, options[:status], layout, options[:locals] || {})
elsif inline = options[:inline]
- add_variables_to_assigns
- render_for_text(@template.render(options), options[:status])
+ render_for_text(@template.render(options.merge(:layout => layout)), options[:status])
elsif action_name = options[:action]
- template = default_template_name(action_name.to_s)
- if options[:layout] && !template_exempt_from_layout?(template)
- render_with_a_layout(:file => template, :status => options[:status], :layout => true)
- else
- render_with_no_layout(:file => template, :status => options[:status])
- end
+ render_for_file(default_template_name(action_name.to_s), options[:status], layout)
elsif xml = options[:xml]
response.content_type ||= Mime::XML
@@ -914,36 +899,26 @@ def render(options = nil, extra_options = {}, &block) #:doc:
response.content_type ||= Mime::JSON
render_for_text(json, options[:status])
- elsif partial = options[:partial]
- partial = default_template_name if partial == true
- add_variables_to_assigns
-
- if collection = options[:collection]
- render_for_text(
- @template.send!(:render_partial_collection, partial, collection,
- options[:spacer_template], options[:locals], options[:as]), options[:status]
- )
+ elsif options[:partial]
+ options[:partial] = default_template_name if options[:partial] == true
+ if layout
+ render_for_text(@template.render(:text => @template.render(options), :layout => layout), options[:status])
else
- render_for_text(
- @template.send!(:render_partial, partial,
- options[:object], options[:locals]), options[:status]
- )
+ render_for_text(@template.render(options), options[:status])
end
elsif options[:update]
- add_variables_to_assigns
- @template.send! :evaluate_assigns
+ @template.send(:_evaluate_assigns_and_ivars)
generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(@template, &block)
response.content_type = Mime::JS
render_for_text(generator.to_s, options[:status])
elsif options[:nothing]
- # Safari doesn't pass the headers of the return if the response is zero length
- render_for_text(" ", options[:status])
+ render_for_text(nil, options[:status])
else
- render_for_file(default_template_name, options[:status], true)
+ render_for_file(default_template_name, options[:status], layout)
end
end
end
@@ -954,7 +929,6 @@ def render_to_string(options = nil, &block) #:doc:
render(options, &block)
ensure
erase_render_results
- forget_variables_added_to_assigns
reset_variables_added_to_assigns
end
@@ -1139,10 +1113,9 @@ def reset_session #:doc:
private
- def render_for_file(template_path, status = nil, use_full_path = nil, locals = {}) #:nodoc:
- add_variables_to_assigns
+ def render_for_file(template_path, status = nil, layout = nil, locals = {}) #:nodoc:
logger.info("Rendering #{template_path}" + (status ? " (#{status})" : '')) if logger
- render_for_text(@template.render(:file => template_path, :locals => locals), status)
+ render_for_text @template.render(:file => template_path, :locals => locals, :layout => layout), status
end
def render_for_text(text = nil, status = nil, append_response = false) #:nodoc:
@@ -1154,13 +1127,17 @@ def render_for_text(text = nil, status = nil, append_response = false) #:nodoc:
response.body ||= ''
response.body << text.to_s
else
- response.body = text.is_a?(Proc) ? text : text.to_s
+ response.body = case text
+ when Proc then text
+ when nil then " " # Safari doesn't pass the headers of the return if the response is zero length
+ else text.to_s
+ end
end
end
def initialize_template_class(response)
response.template = ActionView::Base.new(self.class.view_paths, {}, self)
- response.template.extend self.class.master_helper_module
+ response.template.helpers.send :include, self.class.master_helper_module
response.redirected_to = nil
@performed_render = @performed_redirect = false
end
@@ -1173,7 +1150,6 @@ def assign_shortcuts(request, response)
@_session = @_response.session
@template = @_response.template
- @assigns = @_response.template.assigns
@_headers = @_response.headers
end
@@ -1201,7 +1177,7 @@ def perform_action
elsif respond_to? :method_missing
method_missing action_name
default_render unless performed?
- elsif template_exists? && template_public?
+ elsif template_exists?
default_render
else
raise UnknownAction, "No action responded to #{action_name}. Actions: #{action_methods.sort.to_sentence}", caller
@@ -1217,13 +1193,9 @@ def assign_names
end
def assign_default_content_type_and_charset
- response.content_type ||= Mime::HTML
- response.charset ||= self.class.default_charset unless sending_file?
- end
-
- def sending_file?
- response.headers["Content-Transfer-Encoding"] == "binary"
+ response.assign_default_content_type_and_charset!
end
+ deprecate :assign_default_content_type_and_charset => :'response.assign_default_content_type_and_charset!'
def action_methods
self.class.action_methods
@@ -1241,27 +1213,10 @@ def self.action_methods
hidden_actions
end
- def add_variables_to_assigns
- unless @variables_added
- add_instance_variables_to_assigns
- @variables_added = true
- end
- end
-
- def forget_variables_added_to_assigns
- @variables_added = nil
- end
-
def reset_variables_added_to_assigns
@template.instance_variable_set("@assigns_added", nil)
end
- def add_instance_variables_to_assigns
- (instance_variable_names - @@protected_view_variables).each do |var|
- @assigns[var[1..-1]] = instance_variable_get(var)
- end
- end
-
def request_origin
# this *needs* to be cached!
# otherwise you'd get different results if calling it more than once
@@ -1277,16 +1232,7 @@ def close_session
end
def template_exists?(template_name = default_template_name)
- @template.file_exists?(template_name)
- end
-
- def template_public?(template_name = default_template_name)
- @template.file_public?(template_name)
- end
-
- def template_exempt_from_layout?(template_name = default_template_name)
- template_name = @template.pick_template(template_name).to_s if @template
- @@exempt_from_layout.any? { |ext| template_name =~ ext }
+ @template.send(:_pick_template, template_name) ? true : false
rescue ActionView::MissingTemplate
false
end
View
4 actionpack/lib/action_controller/caching/actions.rb
@@ -90,7 +90,7 @@ def before(controller)
set_content_type!(controller, cache_path.extension)
options = { :text => cache }
options.merge!(:layout => true) if cache_layout?
- controller.send!(:render, options)
+ controller.__send__(:render, options)
false
else
controller.action_cache_path = cache_path
@@ -121,7 +121,7 @@ def cache_layout?
end
def content_for_layout(controller)
- controller.response.layout && controller.response.template.instance_variable_get('@content_for_layout')
+ controller.response.layout && controller.response.template.instance_variable_get('@cached_content_for_layout')
end
end
View
6 actionpack/lib/action_controller/caching/sweeping.rb
@@ -83,13 +83,13 @@ def callback(timing)
controller_callback_method_name = "#{timing}_#{controller.controller_name.underscore}"
action_callback_method_name = "#{controller_callback_method_name}_#{controller.action_name}"
- send!(controller_callback_method_name) if respond_to?(controller_callback_method_name, true)
- send!(action_callback_method_name) if respond_to?(action_callback_method_name, true)
+ __send__(controller_callback_method_name) if respond_to?(controller_callback_method_name, true)
+ __send__(action_callback_method_name) if respond_to?(action_callback_method_name, true)
end
def method_missing(method, *arguments)
return if @controller.nil?
- @controller.send!(method, *arguments)
+ @controller.__send__(method, *arguments)
end
end
end
View
6 actionpack/lib/action_controller/cgi_process.rb
@@ -48,7 +48,7 @@ class SessionFixationAttempt < StandardError #:nodoc:
def initialize(cgi, session_options = {})
@cgi = cgi
@session_options = session_options
- @env = @cgi.send!(:env_table)
+ @env = @cgi.__send__(:env_table)
super()
end
@@ -107,7 +107,7 @@ def reset_session
end
def method_missing(method_id, *arguments)
- @cgi.send!(method_id, *arguments) rescue super
+ @cgi.__send__(method_id, *arguments) rescue super
end
private
@@ -164,7 +164,7 @@ def out(output = $stdout)
begin
output.write(@cgi.header(@headers))
- if @cgi.send!(:env_table)['REQUEST_METHOD'] == 'HEAD'
+ if @cgi.__send__(:env_table)['REQUEST_METHOD'] == 'HEAD'
return
elsif @body.respond_to?(:call)
# Flush the output now in case the @body Proc uses
View
5 actionpack/lib/action_controller/components.rb
@@ -38,6 +38,7 @@ module Components
def self.included(base) #:nodoc:
base.class_eval do
include InstanceMethods
+ include ActiveSupport::Deprecation
extend ClassMethods
helper HelperMethods
@@ -64,7 +65,7 @@ def process_with_components(request, response, parent_controller = nil) #:nodoc:
module HelperMethods
def render_component(options)
- @controller.send!(:render_component_as_string, options)
+ @controller.__send__(:render_component_as_string, options)
end
end
@@ -82,6 +83,7 @@ def render_component(options) #:doc:
render_for_text(component_response(options, true).body, response.headers["Status"])
end
end
+ deprecate :render_component => "Please install render_component plugin from http://github.com/rails/render_component/tree/master"
# Returns the component response as a string
def render_component_as_string(options) #:doc:
@@ -95,6 +97,7 @@ def render_component_as_string(options) #:doc:
end
end
end
+ deprecate :render_component_as_string => "Please install render_component plugin from http://github.com/rails/render_component/tree/master"
def flash_with_components(refresh = false) #:nodoc:
if !defined?(@_flash) || refresh
View
6 actionpack/lib/action_controller/dispatcher.rb
@@ -24,7 +24,7 @@ def define_dispatcher_callbacks(cache_classes)
to_prepare(:activerecord_instantiate_observers) { ActiveRecord::Base.instantiate_observers }
end
- after_dispatch :flush_logger if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER.respond_to?(:flush)
+ after_dispatch :flush_logger if Base.logger && Base.logger.respond_to?(:flush)
end
# Backward-compatible class method takes CGI-specific args. Deprecated
@@ -44,7 +44,7 @@ def dispatch(cgi = nil, session_options = CgiRequest::DEFAULT_SESSION_OPTIONS, o
def to_prepare(identifier = nil, &block)
@prepare_dispatch_callbacks ||= ActiveSupport::Callbacks::CallbackChain.new
callback = ActiveSupport::Callbacks::Callback.new(:prepare_dispatch, block, :identifier => identifier)
- @prepare_dispatch_callbacks | callback
+ @prepare_dispatch_callbacks.replace_or_append!(callback)
end
# If the block raises, send status code as a last-ditch response.
@@ -142,7 +142,7 @@ def cleanup_application
end
def flush_logger
- RAILS_DEFAULT_LOGGER.flush
+ Base.logger.flush
end
protected
View
8 actionpack/lib/action_controller/filters.rb
@@ -199,8 +199,8 @@ def around_proc
Proc.new do |controller, action|
method.before(controller)
- if controller.send!(:performed?)
- controller.send!(:halt_filter_chain, method, :rendered_or_redirected)
+ if controller.__send__(:performed?)
+ controller.__send__(:halt_filter_chain, method, :rendered_or_redirected)
else
begin
action.call
@@ -223,8 +223,8 @@ def before?
def call(controller, &block)
super
- if controller.send!(:performed?)
- controller.send!(:halt_filter_chain, method, :rendered_or_redirected)
+ if controller.__send__(:performed?)
+ controller.__send__(:halt_filter_chain, method, :rendered_or_redirected)
end
end
end
View
4 actionpack/lib/action_controller/helpers.rb
@@ -204,8 +204,8 @@ def inherited_with_helper(child)
begin
child.master_helper_module = Module.new
- child.master_helper_module.send! :include, master_helper_module
- child.send! :default_helper_module!
+ child.master_helper_module.__send__ :include, master_helper_module
+ child.__send__ :default_helper_module!
rescue MissingSourceFile => e
raise unless e.is_missing?("helpers/#{child.controller_path}_helper")
end
View
2  actionpack/lib/action_controller/http_authentication.rb
@@ -117,7 +117,7 @@ def encode_credentials(user_name, password)
def authentication_request(controller, realm)
controller.headers["WWW-Authenticate"] = %(Basic realm="#{realm.gsub(/"/, "")}")
- controller.send! :render, :text => "HTTP Basic: Access denied.\n", :status => :unauthorized
+ controller.__send__ :render, :text => "HTTP Basic: Access denied.\n", :status => :unauthorized
end
end
end
View
86 actionpack/lib/action_controller/integration.rb
@@ -228,21 +228,6 @@ def url_for(options)
end
private
- class StubCGI < CGI #:nodoc:
- attr_accessor :stdinput, :stdoutput, :env_table
-
- def initialize(env, stdinput = nil)
- self.env_table = env
- self.stdoutput = StringIO.new
-
- super
-
- stdinput.set_encoding(Encoding::BINARY) if stdinput.respond_to?(:set_encoding)
- stdinput.force_encoding(Encoding::BINARY) if stdinput.respond_to?(:force_encoding)
- @stdinput = stdinput.is_a?(IO) ? stdinput : StringIO.new(stdinput || '')
- end
- end
-
# Tailors the session based on the given URI, setting the HTTPS value
# and the hostname.
def interpret_uri(path)
@@ -290,9 +275,8 @@ def process(method, path, parameters = nil, headers = nil)
ActionController::Base.clear_last_instantiation!
- cgi = StubCGI.new(env, data)
- ActionController::Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, cgi.stdoutput)
- @result = cgi.stdoutput.string
+ env['rack.input'] = data.is_a?(IO) ? data : StringIO.new(data || '')
+ @status, @headers, result_body = ActionController::Dispatcher.new.call(env)
@request_count += 1
@controller = ActionController::Base.last_instantiation
@@ -306,32 +290,34 @@ def process(method, path, parameters = nil, headers = nil)
@html_document = nil
- parse_result
- return status
- rescue MultiPartNeededException
- boundary = "----------XnJLe9ZIbbGUYtzPQJ16u1"
- status = process(method, path, multipart_body(parameters, boundary), (headers || {}).merge({"CONTENT_TYPE" => "multipart/form-data; boundary=#{boundary}"}))
- return status
- end
+ # Inject status back in for backwords compatibility with CGI
+ @headers['Status'] = @status
- # Parses the result of the response and extracts the various values,
- # like cookies, status, headers, etc.
- def parse_result
- response_headers, result_body = @result.split(/\r\n\r\n/, 2)
+ @status, @status_message = @status.split(/ /)
+ @status = @status.to_i
- @headers = Hash.new { |h,k| h[k] = [] }
- response_headers.to_s.each_line do |line|
- key, value = line.strip.split(/:\s*/, 2)
- @headers[key.downcase] << value
+ cgi_headers = Hash.new { |h,k| h[k] = [] }
+ @headers.each do |key, value|
+ cgi_headers[key.downcase] << value
end
+ cgi_headers['set-cookie'] = cgi_headers['set-cookie'].first
+ @headers = cgi_headers
- (@headers['set-cookie'] || [] ).each do |string|
- name, value = string.match(/^([^=]*)=([^;]*);/)[1,2]
+ @response.headers['cookie'] ||= []
+ (@headers['set-cookie'] || []).each do |cookie|
+ name, value = cookie.match(/^([^=]*)=([^;]*);/)[1,2]
@cookies[name] = value
+
+ # Fake CGI cookie header
+ # DEPRECATE: Use response.headers["Set-Cookie"] instead
+ @response.headers['cookie'] << CGI::Cookie::new("name" => name, "value" => value)
end
- @status, @status_message = @headers["status"].first.to_s.split(/ /)
- @status = @status.to_i
+ return status
+ rescue MultiPartNeededException
+ boundary = "----------XnJLe9ZIbbGUYtzPQJ16u1"
+ status = process(method, path, multipart_body(parameters, boundary), (headers || {}).merge({"CONTENT_TYPE" => "multipart/form-data; boundary=#{boundary}"}))
+ return status
end
# Encode the cookies hash in a format suitable for passing to a
@@ -344,13 +330,15 @@ def encode_cookies
# Get a temporary URL writer object
def generic_url_rewriter
- cgi = StubCGI.new('REQUEST_METHOD' => "GET",
- 'QUERY_STRING' => "",
- "REQUEST_URI" => "/",
- "HTTP_HOST" => host,
- "SERVER_PORT" => https? ? "443" : "80",
- "HTTPS" => https? ? "on" : "off")
- ActionController::UrlRewriter.new(ActionController::CgiRequest.new(cgi), {})
+ env = {
+ 'REQUEST_METHOD' => "GET",
+ 'QUERY_STRING' => "",
+ "REQUEST_URI" => "/",
+ "HTTP_HOST" => host,
+ "SERVER_PORT" => https? ? "443" : "80",
+ "HTTPS" => https? ? "on" : "off"
+ }
+ ActionController::UrlRewriter.new(ActionController::RackRequest.new(env), {})
end
def name_with_prefix(prefix, name)
@@ -451,12 +439,12 @@ def reset!
end
%w(get post put head delete cookies assigns
- xml_http_request get_via_redirect post_via_redirect).each do |method|
+ xml_http_request xhr get_via_redirect post_via_redirect).each do |method|
define_method(method) do |*args|
reset! unless @integration_session
# reset the html_document variable, but only for new get/post calls
@html_document = nil unless %w(cookies assigns).include?(method)
- returning @integration_session.send!(method, *args) do
+ returning @integration_session.__send__(method, *args) do
copy_session_variables!
end
end
@@ -481,12 +469,12 @@ def open_session
self.class.fixture_table_names.each do |table_name|
name = table_name.tr(".", "_")
next unless respond_to?(name)
- extras.send!(:define_method, name) { |*args| delegate.send(name, *args) }
+ extras.__send__(:define_method, name) { |*args| delegate.send(name, *args) }
end
end
# delegate add_assertion to the test case
- extras.send!(:define_method, :add_assertion) { test_result.add_assertion }
+ extras.__send__(:define_method, :add_assertion) { test_result.add_assertion }
session.extend(extras)
session.delegate = self
session.test_result = @_result
@@ -500,7 +488,7 @@ def open_session
def copy_session_variables! #:nodoc:
return unless @integration_session
%w(controller response request).each do |var|
- instance_variable_set("@#{var}", @integration_session.send!(var))
+ instance_variable_set("@#{var}", @integration_session.__send__(var))
end
end
View
80 actionpack/lib/action_controller/layout.rb
@@ -3,11 +3,6 @@ module Layout #:nodoc:
def self.included(base)
base.extend(ClassMethods)
base.class_eval do
- # NOTE: Can't use alias_method_chain here because +render_without_layout+ is already
- # defined as a publicly exposed method
- alias_method :render_with_no_layout, :render
- alias_method :render, :render_with_a_layout
-
class << self
alias_method_chain :inherited, :layout
end
@@ -169,17 +164,17 @@ module ClassMethods
# performance and have access to them as any normal template would.
def layout(template_name, conditions = {}, auto = false)
add_layout_conditions(conditions)
- write_inheritable_attribute "layout", template_name
- write_inheritable_attribute "auto_layout", auto
+ write_inheritable_attribute(:layout, template_name)
+ write_inheritable_attribute(:auto_layout, auto)
end
def layout_conditions #:nodoc:
- @layout_conditions ||= read_inheritable_attribute("layout_conditions")
+ @layout_conditions ||= read_inheritable_attribute(:layout_conditions)
end
def default_layout(format) #:nodoc:
- layout = read_inheritable_attribute("layout")
- return layout unless read_inheritable_attribute("auto_layout")
+ layout = read_inheritable_attribute(:layout)
+ return layout unless read_inheritable_attribute(:auto_layout)
@default_layout ||= {}
@default_layout[format] ||= default_layout_with_format(format, layout)
@default_layout[format]
@@ -199,7 +194,7 @@ def inherited_with_layout(child)
end
def add_layout_conditions(conditions)
- write_inheritable_hash "layout_conditions", normalize_conditions(conditions)
+ write_inheritable_hash(:layout_conditions, normalize_conditions(conditions))
end
def normalize_conditions(conditions)
@@ -221,10 +216,10 @@ def default_layout_with_format(format, layout)
# object). If the layout was defined without a directory, layouts is assumed. So <tt>layout "weblog/standard"</tt> will return
# weblog/standard, but <tt>layout "standard"</tt> will return layouts/standard.
def active_layout(passed_layout = nil)
- layout = passed_layout || self.class.default_layout(response.template.template_format)
+ layout = passed_layout || self.class.default_layout(default_template_format)
active_layout = case layout
when String then layout
- when Symbol then send!(layout)
+ when Symbol then __send__(layout)
when Proc then layout.call(self)
end
@@ -240,51 +235,24 @@ def active_layout(passed_layout = nil)
end
end
- protected
- def render_with_a_layout(options = nil, extra_options = {}, &block) #:nodoc:
- template_with_options = options.is_a?(Hash)
-
- if (layout = pick_layout(template_with_options, options)) && apply_layout?(template_with_options, options)
- options = options.merge :layout => false if template_with_options
- logger.info("Rendering template within #{layout}") if logger
-
- content_for_layout = render_with_no_layout(options, extra_options, &block)
- erase_render_results
- add_variables_to_assigns
- @template.instance_variable_set("@content_for_layout", content_for_layout)
- response.layout = layout
- status = template_with_options ? options[:status] : nil
- render_for_text(@template.render(layout), status)
- else
- render_with_no_layout(options, extra_options, &block)
- end
- end
-
-
private
- def apply_layout?(template_with_options, options)
- return false if options == :update
- template_with_options ? candidate_for_layout?(options) : !template_exempt_from_layout?
- end
-
def candidate_for_layout?(options)
- (options.has_key?(:layout) && options[:layout] != false) ||
- options.values_at(:text, :xml, :json, :file, :inline, :partial, :nothing).compact.empty? &&
- !template_exempt_from_layout?(options[:template] || default_template_name(options[:action]))
+ options.values_at(:text, :xml, :json, :file, :inline, :partial, :nothing, :update).compact.empty? &&
+ !@template.__send__(:_exempt_from_layout?, options[:template] || default_template_name(options[:action]))
end
- def pick_layout(template_with_options, options)
- if template_with_options
- case layout = options[:layout]
- when FalseClass
- nil
- when NilClass, TrueClass
- active_layout if action_has_layout?
- else
- active_layout(layout)
+ def pick_layout(options)
+ if options.has_key?(:layout)
+ case layout = options.delete(:layout)
+ when FalseClass
+ nil
+ when NilClass, TrueClass
+ active_layout if action_has_layout? && !@template.__send__(:_exempt_from_layout?, default_template_name)
+ else
+ active_layout(layout)
end
else
- active_layout if action_has_layout?
+ active_layout if action_has_layout? && candidate_for_layout?(options)
end
end
@@ -304,7 +272,13 @@ def action_has_layout?
end
def layout_directory?(layout_name)
- @template.file_exists?("#{File.join('layouts', layout_name)}.#{@template.template_format}")
+ @template.__send__(:_pick_template, "#{File.join('layouts', layout_name)}.#{@template.template_format}") ? true : false
+ rescue ActionView::MissingTemplate
+ false
+ end
+
+ def default_template_format
+ response.template.template_format
end
end
end
View
2  actionpack/lib/action_controller/mime_type.rb
@@ -1,3 +1,5 @@
+require 'set'
+
module Mime
SET = []
EXTENSION_LOOKUP = Hash.new { |h, k| h[k] = Type.new(k) unless k.blank? }
View
22 actionpack/lib/action_controller/polymorphic_routes.rb
@@ -102,7 +102,13 @@ def polymorphic_url(record_or_hash_or_array, options = {})
args << format if format
named_route = build_named_route_call(record_or_hash_or_array, namespace, inflection, options)
- send!(named_route, *args)
+
+ url_options = options.except(:action, :routing_type, :format)
+ unless url_options.empty?
+ args.last.kind_of?(Hash) ? args.last.merge!(url_options) : args << url_options
+ end
+
+ __send__(named_route, *args)
end
# Returns the path component of a URL for the given record. It uses
@@ -114,19 +120,19 @@ def polymorphic_path(record_or_hash_or_array, options = {})
%w(edit new formatted).each do |action|
module_eval <<-EOT, __FILE__, __LINE__
- def #{action}_polymorphic_url(record_or_hash)
- polymorphic_url(record_or_hash, :action => "#{action}")
+ def #{action}_polymorphic_url(record_or_hash, options = {})
+ polymorphic_url(record_or_hash, options.merge(:action => "#{action}"))
end
- def #{action}_polymorphic_path(record_or_hash)
- polymorphic_url(record_or_hash, :action => "#{action}", :routing_type => :path)
+ def #{action}_polymorphic_path(record_or_hash, options = {})
+ polymorphic_url(record_or_hash, options.merge(:action => "#{action}", :routing_type => :path))
end
EOT
end
private
def action_prefix(options)
- options[:action] ? "#{options[:action]}_" : ""
+ options[:action] ? "#{options[:action]}_" : options[:format] ? "formatted_" : ""
end
def routing_type(options)
@@ -143,7 +149,7 @@ def build_named_route_call(records, namespace, inflection, options = {})
if parent.is_a?(Symbol) || parent.is_a?(String)
string << "#{parent}_"
else
- string << "#{RecordIdentifier.send!("singular_class_name", parent)}_"
+ string << "#{RecordIdentifier.__send__("singular_class_name", parent)}_"
end
end
end
@@ -151,7 +157,7 @@ def build_named_route_call(records, namespace, inflection, options = {})
if record.is_a?(Symbol) || record.is_a?(String)
route << "#{record}_"
else
- route << "#{RecordIdentifier.send!("#{inflection}_class_name", record)}_"
+ route << "#{RecordIdentifier.__send__("#{inflection}_class_name", record)}_"
end
action_prefix(options) + namespace + route + routing_type(options).to_s
View
102 actionpack/lib/action_controller/rack_process.rb
@@ -25,7 +25,7 @@ def initialize(env, session_options = DEFAULT_SESSION_OPTIONS)
end
%w[ AUTH_TYPE GATEWAY_INTERFACE PATH_INFO
- PATH_TRANSLATED QUERY_STRING REMOTE_HOST
+ PATH_TRANSLATED REMOTE_HOST
REMOTE_IDENT REMOTE_USER SCRIPT_NAME
SERVER_NAME SERVER_PROTOCOL
@@ -37,6 +37,15 @@ def initialize(env, session_options = DEFAULT_SESSION_OPTIONS)
end
end
+ def query_string
+ qs = super
+ if !qs.blank?
+ qs
+ else
+ @env['QUERY_STRING']
+ end
+ end
+
def body_stream #:nodoc:
@env['rack.input']
end
@@ -143,23 +152,30 @@ def session_options_with_string_keys
end
class RackResponse < AbstractResponse #:nodoc:
- attr_accessor :status
-
def initialize(request)
- @request = request
+ @cgi = request.cgi
@writer = lambda { |x| @body << x }
@block = nil
super()
end
+ # Retrieve status from instance variable if has already been delete
+ def status
+ @status || super
+ end
+
def out(output = $stdout, &block)
+ # Nasty hack because CGI sessions are closed after the normal
+ # prepare! statement
+ set_cookies!
+
@block = block
- normalize_headers(@headers)
- if [204, 304].include?(@status.to_i)
- @headers.delete "Content-Type"
- [status, @headers.to_hash, []]
+ @status = headers.delete("Status")
+ if [204, 304].include?(status.to_i)
+ headers.delete("Content-Type")
+ [status, headers.to_hash, []]
else
- [status, @headers.to_hash, self]
+ [status, headers.to_hash, self]
end
end
alias to_a out
@@ -191,43 +207,57 @@ def empty?
@block == nil && @body.empty?
end
- private
- def normalize_headers(options = "text/html")
- if options.is_a?(String)
- headers['Content-Type'] = options unless headers['Content-Type']
- else
- headers['Content-Length'] = options.delete('Content-Length').to_s if options['Content-Length']
+ def prepare!
+ super
- headers['Content-Type'] = options.delete('type') || "text/html"
- headers['Content-Type'] += "; charset=" + options.delete('charset') if options['charset']
+ convert_language!
+ convert_expires!
+ set_status!
+ # set_cookies!
+ end
- headers['Content-Language'] = options.delete('language') if options['language']
- headers['Expires'] = options.delete('expires') if options['expires']
+ private
+ def convert_language!
+ headers["Content-Language"] = headers.delete("language") if headers["language"]
+ end
- @status = options.delete('Status') || "200 OK"
+ def convert_expires!
+ headers["Expires"] = headers.delete("") if headers["expires"]
+ end
- # Convert 'cookie' header to 'Set-Cookie' headers.
- # Because Set-Cookie header can appear more the once in the response body,
- # we store it in a line break separated string that will be translated to
- # multiple Set-Cookie header by the handler.
- if cookie = options.delete('cookie')
- cookies = []
+ def convert_content_type!
+ super
+ headers['Content-Type'] = headers.delete('type') || "text/html"
+ headers['Content-Type'] += "; charset=" + headers.delete('charset') if headers['charset']
+ end
- case cookie
- when Array then cookie.each { |c| cookies << c.to_s }
- when Hash then cookie.each { |_, c| cookies << c.to_s }
- else cookies << cookie.to_s
- end
+ def set_content_length!
+ super
+ headers["Content-Length"] = headers["Content-Length"].to_s if headers["Content-Length"]
+ end
- @request.cgi.output_cookies.each { |c| cookies << c.to_s } if @request.cgi.output_cookies
+ def set_status!
+ self.status ||= "200 OK"
+ end
- headers['Set-Cookie'] = [headers['Set-Cookie'], cookies].flatten.compact
+ def set_cookies!
+ # Convert 'cookie' header to 'Set-Cookie' headers.
+ # Because Set-Cookie header can appear more the once in the response body,
+ # we store it in a line break separated string that will be translated to
+ # multiple Set-Cookie header by the handler.
+ if cookie = headers.delete('cookie')
+ cookies = []
+
+ case cookie
+ when Array then cookie.each { |c| cookies << c.to_s }
+ when Hash then cookie.each { |_, c| cookies << c.to_s }
+ else cookies << cookie.to_s
end
- options.each { |k,v| headers[k] = v }
- end
+ @cgi.output_cookies.each { |c| cookies << c.to_s } if @cgi.output_cookies
- ""
+ headers['Set-Cookie'] = [headers['Set-Cookie'], cookies].flatten.compact
+ end
end
end
View
10 actionpack/lib/action_controller/request.rb 100644 → 100755
@@ -102,7 +102,7 @@ def accepts
def if_modified_since
if since = env['HTTP_IF_MODIFIED_SINCE']
- Time.rfc2822(since)
+ Time.rfc2822(since) rescue nil
end
end
memoize :if_modified_since
@@ -199,10 +199,12 @@ def xml_http_request?
# delimited list in the case of multiple chained proxies; the last
# address which is not trusted is the originating IP.
def remote_ip
- if TRUSTED_PROXIES !~ @env['REMOTE_ADDR']
- return @env['REMOTE_ADDR']
- end
+ remote_addr_list = @env['REMOTE_ADDR'] && @env['REMOTE_ADDR'].split(',').collect(&:strip)
+ unless remote_addr_list.blank?
+ not_trusted_addrs = remote_addr_list.reject {|addr| addr =~ TRUSTED_PROXIES}