Skip to content
Browse files

Merge commit 'rails/master'

Conflicts:
	activerecord/lib/active_record/associations.rb
  • Loading branch information...
2 parents c1cbf02 + 62fd1d3 commit 3de59e916d6a3d4eab202cf0c99b1f88905a3b43 @miloops miloops committed Jul 31, 2009
Showing with 5,431 additions and 1,591 deletions.
  1. +2 −0 .gitignore
  2. +2 −1 Rakefile
  3. +1 −1 actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/obsolete.rb
  4. +1 −1 actionpack/lib/action_controller/base/http_authentication.rb
  5. +215 −47 actionpack/lib/action_controller/base/mime_responds.rb
  6. +1 −2 actionpack/lib/action_controller/base/renderer.rb
  7. +1 −2 actionpack/lib/action_controller/base/request_forgery_protection.rb
  8. +1 −1 actionpack/lib/action_controller/routing.rb
  9. +1 −1 actionpack/lib/action_controller/routing/generation/url_rewriter.rb
  10. +1 −1 actionpack/lib/action_controller/routing/route_set.rb
  11. +2 −2 actionpack/lib/action_controller/testing/test_case.rb
  12. +1 −1 actionpack/lib/action_dispatch/http/mime_type.rb
  13. +4 −2 actionpack/lib/action_dispatch/http/mime_types.rb
  14. +34 −8 actionpack/lib/action_dispatch/http/request.rb
  15. +24 −6 actionpack/lib/action_view/helpers/active_model_helper.rb
  16. +1 −1 actionpack/lib/action_view/helpers/asset_tag_helper.rb
  17. +5 −5 actionpack/lib/action_view/helpers/date_helper.rb
  18. +21 −21 actionpack/lib/action_view/helpers/form_options_helper.rb
  19. +4 −1 actionpack/lib/action_view/helpers/tag_helper.rb
  20. +2 −2 actionpack/lib/action_view/helpers/text_helper.rb
  21. +48 −49 actionpack/lib/action_view/helpers/url_helper.rb
  22. +189 −15 actionpack/test/controller/mime_responds_test.rb
  23. +45 −6 actionpack/test/dispatch/request_test.rb
  24. +1 −1 actionpack/test/fixtures/public/.gitignore
  25. +1 −0 actionpack/test/fixtures/respond_with/using_defaults.html.erb
  26. +1 −0 actionpack/test/fixtures/respond_with/using_defaults.js.rjs
  27. +1 −0 actionpack/test/fixtures/respond_with/using_defaults_with_type_list.js.rjs
  28. +1 −0 actionpack/test/fixtures/respond_with/using_defaults_with_type_list.xml.builder
  29. +1 −0 actionpack/test/fixtures/respond_with/using_resource.html.erb
  30. +5 −2 actionpack/test/template/active_record_helper_i18n_test.rb
  31. +10 −0 actionpack/test/template/active_record_helper_test.rb
  32. +4 −4 actionpack/test/template/asset_tag_helper_test.rb
  33. +2 −1 activemodel/lib/active_model/naming.rb
  34. +6 −2 activemodel/lib/active_model/serializers/xml.rb
  35. +23 −0 activemodel/test/cases/serializeration/xml_serialization_test.rb
  36. +4 −0 activemodel/test/models/contact.rb
  37. +11 −2 activerecord/lib/active_record.rb
  38. +2 −2 activerecord/lib/active_record/association_preload.rb
  39. +71 −5 activerecord/lib/active_record/associations.rb
  40. +2 −2 activerecord/lib/active_record/associations/association_collection.rb
  41. +64 −245 activerecord/lib/active_record/attribute_methods.rb
  42. +33 −0 activerecord/lib/active_record/attribute_methods/before_type_cast.rb
  43. +187 −0 activerecord/lib/active_record/attribute_methods/dirty.rb
  44. +44 −0 activerecord/lib/active_record/attribute_methods/primary_key.rb
  45. +37 −0 activerecord/lib/active_record/attribute_methods/query.rb
  46. +116 −0 activerecord/lib/active_record/attribute_methods/read.rb
  47. +60 −0 activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
  48. +37 −0 activerecord/lib/active_record/attribute_methods/write.rb
  49. +45 −100 activerecord/lib/active_record/base.rb
  50. +17 −1 activerecord/lib/active_record/callbacks.rb
  51. +1 −1 activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
  52. +8 −0 activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
  53. +0 −186 activerecord/lib/active_record/dirty.rb
  54. +1 −1 activerecord/lib/active_record/fixtures.rb
  55. +3 −3 activerecord/lib/active_record/migration.rb
  56. +1 −6 activerecord/lib/active_record/named_scope.rb
  57. +1 −1 activerecord/lib/active_record/nested_attributes.rb
  58. +15 −0 activerecord/lib/active_record/serializers/xml_serializer.rb
  59. +1 −1 activerecord/lib/active_record/validations.rb
  60. +0 −4 activerecord/test/cases/attribute_methods_test.rb
  61. +0 −5 activerecord/test/cases/base_test.rb
  62. +0 −4 activerecord/test/cases/named_scope_test.rb
  63. +6 −0 activerecord/test/cases/xml_serialization_test.rb
  64. +0 −2 activerecord/test/models/topic.rb
  65. +4 −0 activesupport/lib/active_support/buffered_logger.rb
  66. +3 −3 activesupport/lib/active_support/cache/mem_cache_store.rb
  67. +1 −1 activesupport/lib/active_support/callbacks.rb
  68. +1 −1 activesupport/lib/active_support/core_ext/array/conversions.rb
  69. +1 −1 activesupport/lib/active_support/core_ext/enumerable.rb
  70. +1 −1 activesupport/lib/active_support/core_ext/object/duplicable.rb
  71. +1 −1 activesupport/lib/active_support/core_ext/time/marshal_with_utc_flag.rb
  72. +3 −3 activesupport/lib/active_support/inflector.rb
  73. +2 −2 activesupport/lib/active_support/mini.rb
  74. +55 −55 activesupport/lib/active_support/vendor/tzinfo-0.3.13/tzinfo/ruby_core_support.rb
  75. +1 −1 activesupport/lib/active_support/xml_mini/jdom.rb
  76. +1 −1 activesupport/lib/active_support/xml_mini/nokogiri.rb
  77. +1 −1 activesupport/lib/active_support/xml_mini/rexml.rb
  78. +45 −46 railties/README
  79. +22 −182 railties/Rakefile
  80. +4 −9 railties/bin/rails
  81. +0 −1 railties/guides/files/javascripts/guides.js
  82. BIN railties/guides/images/fxn.jpg
  83. BIN railties/guides/images/fxn.png
  84. +20 −13 railties/guides/source/action_controller_overview.textile
  85. +16 −14 railties/guides/source/action_mailer_basics.textile
  86. +3 −3 railties/guides/source/active_record_basics.textile
  87. +5 −12 railties/guides/source/active_record_querying.textile
  88. +818 −0 railties/guides/source/active_support_overview.textile
  89. +4 −4 railties/guides/source/activerecord_validations_callbacks.textile
  90. +94 −0 railties/guides/source/ajax_on_rails.textile
  91. +44 −9 railties/guides/source/association_basics.textile
  92. +66 −196 railties/guides/source/caching_with_rails.textile
  93. +1 −1 railties/guides/source/configuring.textile
  94. +1 −1 railties/guides/source/contribute.textile
  95. +10 −1 railties/guides/source/contributing_to_rails.textile
  96. +3 −3 railties/guides/source/credits.erb.textile
  97. +1 −1 railties/guides/source/debugging_rails_applications.textile
  98. +15 −13 railties/guides/source/form_helpers.textile
  99. +71 −58 railties/guides/source/getting_started.textile
  100. +25 −58 railties/guides/source/i18n.textile
  101. +1 −1 railties/guides/source/index.erb.textile
  102. +19 −19 railties/guides/source/layouts_and_rendering.textile
  103. +6 −6 railties/guides/source/migrations.textile
  104. +1 −1 railties/guides/source/performance_testing.textile
  105. +1 −1 railties/guides/source/plugins.textile
  106. +226 −6 railties/guides/source/rails_application_templates.textile
  107. +2 −2 railties/guides/source/rails_on_rack.textile
  108. +4 −4 railties/guides/source/routing.textile
  109. +3 −3 railties/guides/source/security.textile
  110. +10 −8 railties/guides/source/testing.textile
  111. +8 −4 railties/lib/commands/destroy.rb
  112. +8 −4 railties/lib/commands/generate.rb
  113. +9 −3 railties/lib/commands/update.rb
  114. +300 −0 railties/lib/generators.rb
  115. +74 −0 railties/lib/generators/action_orm.rb
  116. +263 −0 railties/lib/generators/actions.rb
  117. +57 −0 railties/lib/generators/active_record.rb
  118. +25 −0 railties/lib/generators/active_record/migration/migration_generator.rb
  119. +1 −1 ...ails_generator/generators/components → generators/active_record}/migration/templates/migration.rb
  120. +35 −0 railties/lib/generators/active_record/model/model_generator.rb
  121. +2 −2 ...b/{rails_generator/generators/components → generators/active_record}/model/templates/migration.rb
  122. +1 −1 ...s/lib/{rails_generator/generators/components → generators/active_record}/model/templates/model.rb
  123. +15 −0 railties/lib/generators/active_record/observer/observer_generator.rb
  124. 0 ...{rails_generator/generators/components → generators/active_record}/observer/templates/observer.rb
  125. +20 −0 railties/lib/generators/active_record/session_migration/session_migration_generator.rb
  126. +1 −1 ...erator/generators/components → generators/active_record}/session_migration/templates/migration.rb
  127. +302 −0 railties/lib/generators/base.rb
  128. +8 −0 railties/lib/generators/erb.rb
  129. +21 −0 railties/lib/generators/erb/controller/controller_generator.rb
  130. +2 −0 railties/lib/generators/erb/controller/templates/view.html.erb
  131. +20 −0 railties/lib/generators/erb/mailer/mailer_generator.rb
  132. +3 −0 railties/lib/generators/erb/mailer/templates/view.erb
  133. +54 −0 railties/lib/generators/erb/scaffold/scaffold_generator.rb
  134. 0 ...mponents/scaffold/templates/view_edit.html.erb → generators/erb/scaffold/templates/edit.html.erb}
  135. +2 −2 ...onents/scaffold/templates/view_index.html.erb → generators/erb/scaffold/templates/index.html.erb}
  136. 0 ...s/lib/{rails_generator/generators/components → generators/erb}/scaffold/templates/layout.html.erb
  137. 0 ...components/scaffold/templates/view_new.html.erb → generators/erb/scaffold/templates/new.html.erb}
  138. +2 −2 ...mponents/scaffold/templates/view_show.html.erb → generators/erb/scaffold/templates/show.html.erb}
  139. +9 −7 railties/lib/{rails_generator → generators}/generated_attribute.rb
  140. +65 −0 railties/lib/generators/migration.rb
  141. +162 −0 railties/lib/generators/named_base.rb
  142. 0 railties/lib/{rails_generator/generators/applications → generators/rails}/app/USAGE
  143. +210 −0 railties/lib/generators/rails/app/app_generator.rb
  144. +243 −0 railties/lib/generators/rails/app/templates/README
  145. 0 railties/{fresh_rakefile → lib/generators/rails/app/templates/Rakefile}
  146. 0 railties/{helpers → lib/generators/rails/app/templates/app/controllers}/application_controller.rb
  147. 0 railties/{ → lib/generators/rails/app/templates/app}/helpers/application_helper.rb
  148. 0 ...rs/missing_templates/.gitignore → lib/generators/rails/app/templates/app/models/.empty_directory}
  149. 0 ...tor/templates/.gitignore → lib/generators/rails/app/templates/app/views/layouts/.empty_directory}
  150. 0 railties/{environments → lib/generators/rails/app/templates/config}/boot.rb
  151. 0 railties/{configs → lib/generators/rails/app/templates/config}/databases/frontbase.yml
  152. 0 railties/{configs → lib/generators/rails/app/templates/config}/databases/ibm_db.yml
  153. +6 −6 railties/{configs → lib/generators/rails/app/templates/config}/databases/mysql.yml
  154. 0 railties/{configs → lib/generators/rails/app/templates/config}/databases/oracle.yml
  155. 0 railties/{configs → lib/generators/rails/app/templates/config}/databases/postgresql.yml
  156. 0 railties/{configs → lib/generators/rails/app/templates/config}/databases/sqlite2.yml
  157. 0 railties/{configs → lib/generators/rails/app/templates/config}/databases/sqlite3.yml
  158. +14 −2 railties/{environments → lib/generators/rails/app/templates/config}/environment.rb
  159. 0 railties/{ → lib/generators/rails/app/templates/config}/environments/development.rb
  160. 0 railties/{ → lib/generators/rails/app/templates/config}/environments/production.rb
  161. 0 railties/{ → lib/generators/rails/app/templates/config}/environments/test.rb
  162. 0 railties/{configs → lib/generators/rails/app/templates/config}/initializers/backtrace_silencers.rb
  163. 0 railties/{configs → lib/generators/rails/app/templates/config}/initializers/inflections.rb
  164. 0 railties/{configs → lib/generators/rails/app/templates/config}/initializers/mime_types.rb
  165. 0 railties/{configs → lib/generators/rails/app/templates/config}/initializers/new_rails_defaults.rb
  166. 0 ...rs/session_store.rb → lib/generators/rails/app/templates/config/initializers/session_store.rb.tt}
  167. 0 railties/{configs → lib/generators/rails/app/templates/config}/locales/en.yml
  168. 0 railties/{configs → lib/generators/rails/app/templates/config}/routes.rb
  169. +1 −1 railties/{configs → lib/generators/rails/app/templates/db}/seeds.rb
  170. 0 railties/{dispatches → lib/generators/rails/app/templates/dispatchers}/config.ru
  171. +1 −1 railties/{dispatches → lib/generators/rails/app/templates/dispatchers}/dispatch.fcgi
  172. +1 −1 railties/{dispatches → lib/generators/rails/app/templates/dispatchers}/dispatch.rb
  173. +1 −1 railties/{dispatches → lib/generators/rails/app/templates/dispatchers}/gateway.cgi
  174. 0 railties/{ → lib/generators/rails/app/templates}/doc/README_FOR_APP
  175. 0 railties/{html → lib/generators/rails/app/templates/public}/404.html
  176. 0 railties/{html → lib/generators/rails/app/templates/public}/422.html
  177. 0 railties/{html → lib/generators/rails/app/templates/public}/500.html
  178. 0 railties/{html → lib/generators/rails/app/templates/public}/favicon.ico
  179. 0 railties/{html → lib/generators/rails/app/templates/public}/images/rails.png
  180. 0 railties/{html → lib/generators/rails/app/templates/public}/index.html
  181. 0 railties/{html → lib/generators/rails/app/templates/public}/javascripts/application.js
  182. 0 railties/{html → lib/generators/rails/app/templates/public}/javascripts/controls.js
  183. 0 railties/{html → lib/generators/rails/app/templates/public}/javascripts/dragdrop.js
  184. 0 railties/{html → lib/generators/rails/app/templates/public}/javascripts/effects.js
  185. 0 railties/{html → lib/generators/rails/app/templates/public}/javascripts/prototype.js
  186. 0 railties/{html → lib/generators/rails/app/templates/public}/robots.txt
  187. 0 ...ss/templates/.gitignore → lib/generators/rails/app/templates/public/stylesheets/.empty_directory}
  188. +1 −1 railties/{bin/about → lib/generators/rails/app/templates/script/about.tt}
  189. +1 −1 railties/{bin/console → lib/generators/rails/app/templates/script/console.tt}
  190. +1 −1 railties/{bin/dbconsole → lib/generators/rails/app/templates/script/dbconsole.tt}
  191. +1 −1 railties/{bin/destroy → lib/generators/rails/app/templates/script/destroy.tt}
  192. +1 −1 railties/{bin/generate → lib/generators/rails/app/templates/script/generate.tt}
  193. +1 −1 ...n/performance/benchmarker → lib/generators/rails/app/templates/script/performance/benchmarker.tt}
  194. +1 −1 ...es/{bin/performance/profiler → lib/generators/rails/app/templates/script/performance/profiler.tt}
  195. +1 −1 railties/{bin/plugin → lib/generators/rails/app/templates/script/plugin.tt}
  196. +1 −1 railties/{bin/runner → lib/generators/rails/app/templates/script/runner.tt}
  197. +1 −1 railties/{bin/server → lib/generators/rails/app/templates/script/server.tt}
  198. 0 ...s/missing_class_generator.rb → lib/generators/rails/app/templates/test/fixtures/.empty_directory}
  199. 0 ...ts/mailer/templates/view.rhtml → generators/rails/app/templates/test/functional/.empty_directory}
  200. 0 ...ailer/templates/fixture.rhtml → generators/rails/app/templates/test/integration/.empty_directory}
  201. 0 ...lpers/performance_test.rb → lib/generators/rails/app/templates/test/performance/browsing_test.rb}
  202. 0 railties/{helpers → lib/generators/rails/app/templates/test}/test_helper.rb
  203. 0 railties/{configs/empty.log → lib/generators/rails/app/templates/test/unit/.empty_directory}
  204. +18 −0 railties/lib/generators/rails/controller/USAGE
  205. +14 −0 railties/lib/generators/rails/controller/controller_generator.rb
  206. 0 ...lib/{rails_generator/generators/components → generators/rails}/controller/templates/controller.rb
  207. +11 −0 railties/lib/generators/rails/generator/USAGE
  208. +25 −0 railties/lib/generators/rails/generator/generator_generator.rb
  209. +5 −0 railties/lib/generators/rails/generator/templates/%file_name%_generator.rb.tt
  210. 0 ...tor/generators/components/plugin/templates/USAGE → generators/rails/generator/templates/USAGE.tt}
  211. 0 railties/lib/generators/rails/generator/templates/templates/.empty_directory
  212. +17 −0 railties/lib/generators/rails/helper/USAGE
  213. +13 −0 railties/lib/generators/rails/helper/helper_generator.rb
  214. 0 railties/lib/{rails_generator/generators/components → generators/rails}/helper/templates/helper.rb
  215. +4 −2 railties/lib/{rails_generator/generators/components → generators/rails}/integration_test/USAGE
  216. +7 −0 railties/lib/generators/rails/integration_test/integration_test_generator.rb
  217. +2 −3 railties/lib/{rails_generator/generators/components → generators/rails}/mailer/USAGE
  218. +14 −0 railties/lib/generators/rails/mailer/mailer_generator.rb
  219. +1 −2 railties/lib/{rails_generator/generators/components → generators/rails}/mailer/templates/mailer.rb
  220. 0 railties/lib/{rails_generator/generators/components → generators/rails}/metal/USAGE
  221. +11 −0 railties/lib/generators/rails/metal/metal_generator.rb
  222. 0 railties/lib/{rails_generator/generators/components → generators/rails}/metal/templates/metal.rb
  223. +2 −2 railties/lib/{rails_generator/generators/components → generators/rails}/migration/USAGE
  224. +8 −0 railties/lib/generators/rails/migration/migration_generator.rb
  225. +9 −6 railties/lib/{rails_generator/generators/components → generators/rails}/model/USAGE
  226. +8 −0 railties/lib/generators/rails/model/model_generator.rb
  227. +11 −0 railties/lib/generators/rails/model_subclass/model_subclass_generator.rb
  228. +3 −4 railties/lib/{rails_generator/generators/components → generators/rails}/observer/USAGE
  229. +7 −0 railties/lib/generators/rails/observer/observer_generator.rb
  230. +4 −2 railties/lib/{rails_generator/generators/components → generators/rails}/performance_test/USAGE
  231. +7 −0 railties/lib/generators/rails/performance_test/performance_test_generator.rb
  232. +13 −0 railties/lib/generators/rails/plugin/USAGE
  233. +47 −0 railties/lib/generators/rails/plugin/plugin_generator.rb
  234. 0 railties/lib/{rails_generator/generators/components → generators/rails}/plugin/templates/MIT-LICENSE
  235. 0 railties/lib/{rails_generator/generators/components → generators/rails}/plugin/templates/README
  236. 0 railties/lib/{rails_generator/generators/components → generators/rails}/plugin/templates/Rakefile
  237. 0 railties/lib/{rails_generator/generators/components → generators/rails}/plugin/templates/init.rb
  238. 0 railties/lib/{rails_generator/generators/components → generators/rails}/plugin/templates/install.rb
  239. 0 .../components/plugin/templates/plugin.rb → generators/rails/plugin/templates/lib/%file_name%.rb.tt}
  240. 0 .../plugin/templates/tasks.rake → generators/rails/plugin/templates/tasks/%file_name%_tasks.rake.tt}
  241. 0 ...ties/lib/{rails_generator/generators/components → generators/rails}/plugin/templates/uninstall.rb
  242. +4 −4 railties/lib/{rails_generator/generators/components → generators/rails}/resource/USAGE
  243. +40 −0 railties/lib/generators/rails/resource/resource_generator.rb
  244. +1 −1 railties/lib/{rails_generator/generators/components → generators/rails}/scaffold/USAGE
  245. +12 −0 railties/lib/generators/rails/scaffold/scaffold_generator.rb
  246. +20 −0 railties/lib/generators/rails/scaffold_controller/USAGE
  247. +26 −0 railties/lib/generators/rails/scaffold_controller/scaffold_controller_generator.rb
  248. +14 −12 ...or/generators/components/scaffold → generators/rails/scaffold_controller}/templates/controller.rb
  249. +8 −0 railties/lib/generators/rails/session_migration/USAGE
  250. +8 −0 railties/lib/generators/rails/session_migration/session_migration_generator.rb
  251. +5 −0 railties/lib/generators/rails/stylesheets/USAGE
  252. +9 −0 railties/lib/generators/rails/stylesheets/stylesheets_generator.rb
  253. 0 ...rs/components/scaffold/templates/style.css → generators/rails/stylesheets/templates/scaffold.css}
  254. +8 −0 railties/lib/generators/test_unit.rb
  255. +14 −0 railties/lib/generators/test_unit/controller/controller_generator.rb
  256. 0 ...s_generator/generators/components → generators/test_unit}/controller/templates/functional_test.rb
Sorry, we could not display the entire diff because too many files (420) changed.
View
2 .gitignore
@@ -13,6 +13,8 @@ actionmailer/pkg
activesupport/pkg
railties/pkg
railties/test/500.html
+railties/test/fixtures/tmp
+railties/test/initializer/root/log
railties/doc/guides/html/images
railties/doc/guides/html/stylesheets
benches
View
3 Rakefile
@@ -38,7 +38,8 @@ Rake::RDocTask.new do |rdoc|
rdoc.rdoc_files.include('railties/CHANGELOG')
rdoc.rdoc_files.include('railties/MIT-LICENSE')
rdoc.rdoc_files.include('railties/README')
- rdoc.rdoc_files.include('railties/lib/{*.rb,commands/*.rb,rails/*.rb,rails_generator/*.rb}')
+ rdoc.rdoc_files.include('railties/lib/{*.rb,commands/*.rb,rails/*.rb,generators/*.rb}')
+ rdoc.rdoc_files.exclude('railties/lib/vendor/*')
rdoc.rdoc_files.include('activerecord/README')
rdoc.rdoc_files.include('activerecord/CHANGELOG')
View
2 actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/obsolete.rb
@@ -1,6 +1,6 @@
=begin rdoc
-= Obsolete methods that are depriciated
+= Obsolete methods that are deprecated
If you really want to see them, go to lib/tmail/obsolete.rb and view to your
heart's content.
View
2 actionpack/lib/action_controller/base/http_authentication.rb
@@ -276,7 +276,7 @@ def authentication_request(controller, realm, message = nil)
#
# The nonce is opaque to the client. Composed of Time, and hash of Time with secret
# key from the Rails session secret generated upon creation of project. Ensures
- # the time cannot be modifed by client.
+ # the time cannot be modified by client.
def nonce(time = Time.now)
t = time.to_i
hashed = [t, secret_key]
View
262 actionpack/lib/action_controller/base/mime_responds.rb
@@ -1,5 +1,55 @@
module ActionController #:nodoc:
module MimeResponds #:nodoc:
+ extend ActiveSupport::Concern
+
+ included do
+ class_inheritable_reader :mimes_for_respond_to
+ clear_respond_to
+ end
+
+ module ClassMethods
+ # Defines mimes that are rendered by default when invoking respond_with.
+ #
+ # Examples:
+ #
+ # respond_to :html, :xml, :json
+ #
+ # All actions on your controller will respond to :html, :xml and :json.
+ #
+ # But if you want to specify it based on your actions, you can use only and
+ # except:
+ #
+ # respond_to :html
+ # respond_to :xml, :json, :except => [ :edit ]
+ #
+ # The definition above explicits that all actions respond to :html. And all
+ # actions except :edit respond to :xml and :json.
+ #
+ # You can specify also only parameters:
+ #
+ # respond_to :rjs, :only => :create
+ #
+ def respond_to(*mimes)
+ options = mimes.extract_options!
+
+ only_actions = Array(options.delete(:only))
+ except_actions = Array(options.delete(:except))
+
+ mimes.each do |mime|
+ mime = mime.to_sym
+ mimes_for_respond_to[mime] = {}
+ mimes_for_respond_to[mime][:only] = only_actions unless only_actions.empty?
+ mimes_for_respond_to[mime][:except] = except_actions unless except_actions.empty?
+ end
+ end
+
+ # Clear all mimes in respond_to.
+ #
+ def clear_respond_to
+ write_inheritable_attribute(:mimes_for_respond_to, ActiveSupport::OrderedHash.new)
+ end
+ end
+
# Without web-service support, an action which collects the data for displaying a list of people
# might look something like this:
#
@@ -92,50 +142,187 @@ module MimeResponds #:nodoc:
# environment.rb as follows.
#
# Mime::Type.register "image/jpg", :jpg
- def respond_to(*types, &block)
- raise ArgumentError, "respond_to takes either types or a block, never both" unless types.any? ^ block
- block ||= lambda { |responder| types.each { |type| responder.send(type) } }
- responder = Responder.new(self)
- block.call(responder)
- responder.respond
- end
+ #
+ # Respond to also allows you to specify a common block for different formats by using any:
+ #
+ # def index
+ # @people = Person.find(:all)
+ #
+ # respond_to do |format|
+ # format.html
+ # format.any(:xml, :json) { render request.format.to_sym => @people }
+ # end
+ # end
+ #
+ # In the example above, if the format is xml, it will render:
+ #
+ # render :xml => @people
+ #
+ # Or if the format is json:
+ #
+ # render :json => @people
+ #
+ # Since this is a common pattern, you can use the class method respond_to
+ # with the respond_with method to have the same results:
+ #
+ # class PeopleController < ApplicationController
+ # respond_to :html, :xml, :json
+ #
+ # def index
+ # @people = Person.find(:all)
+ # respond_with(@person)
+ # end
+ # end
+ #
+ # Be sure to check respond_with and respond_to documentation for more examples.
+ #
+ def respond_to(*mimes, &block)
+ options = mimes.extract_options!
+ raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given?
- class Responder #:nodoc:
-
- def initialize(controller)
- @controller = controller
- @request = controller.request
- @response = controller.response
+ resource = options.delete(:with)
+ responder = Responder.new
- @mime_type_priority = @request.formats
+ mimes = collect_mimes_from_class_level if mimes.empty?
+ mimes.each { |mime| responder.send(mime) }
+ block.call(responder) if block_given?
- @order = []
- @responses = {}
+ if format = request.negotiate_mime(responder.order)
+ respond_to_block_or_template_or_resource(format, resource,
+ options, &responder.response_for(format))
+ else
+ head :not_acceptable
end
+ end
- def custom(mime_type, &block)
- mime_type = mime_type.is_a?(Mime::Type) ? mime_type : Mime::Type.lookup(mime_type.to_s)
+ # respond_with allows you to respond an action with a given resource. It
+ # requires that you set your class with a :respond_to method with the
+ # formats allowed:
+ #
+ # class PeopleController < ApplicationController
+ # respond_to :html, :xml, :json
+ #
+ # def index
+ # @people = Person.find(:all)
+ # respond_with(@person)
+ # end
+ # end
+ #
+ # When a request comes with format :xml, the respond_with will first search
+ # for a template as person/index.xml, if the template is not available, it
+ # will see if the given resource responds to :to_xml.
+ #
+ # If neither are available, it will raise an error.
+ #
+ # Extra parameters given to respond_with are used when :to_format is invoked.
+ # This allows you to set status and location for several formats at the same
+ # time. Consider this restful controller response on create for both xml
+ # and json formats:
+ #
+ # class PeopleController < ApplicationController
+ # respond_to :xml, :json
+ #
+ # def create
+ # @person = Person.new(params[:person])
+ #
+ # if @person.save
+ # respond_with(@person, :status => :ok, :location => person_url(@person))
+ # else
+ # respond_with(@person.errors, :status => :unprocessable_entity)
+ # end
+ # end
+ # end
+ #
+ # Finally, respond_with also accepts blocks, as in respond_to. Let's take
+ # the same controller and create action above and add common html behavior:
+ #
+ # class PeopleController < ApplicationController
+ # respond_to :html, :xml, :json
+ #
+ # def create
+ # @person = Person.new(params[:person])
+ #
+ # if @person.save
+ # options = { :status => :ok, :location => person_url(@person) }
+ #
+ # respond_with(@person, options) do |format|
+ # format.html { redirect_to options[:location] }
+ # end
+ # else
+ # respond_with(@person.errors, :status => :unprocessable_entity) do
+ # format.html { render :action => :new }
+ # end
+ # end
+ # end
+ # end
+ #
+ def respond_with(resource, options={}, &block)
+ respond_to(options.merge!(:with => resource), &block)
+ end
- @order << mime_type
+ protected
- @responses[mime_type] ||= Proc.new do
- # TODO: Remove this when new base is merged in
- @controller.formats = [mime_type.to_sym]
- @controller.content_type = mime_type
- @controller.template.formats = [mime_type.to_sym]
+ def respond_to_block_or_template_or_resource(format, resource, options)
+ self.formats = [format.to_sym]
+ return yield if block_given?
- block_given? ? block.call : @controller.send(:render, :action => @controller.action_name)
+ begin
+ default_render
+ rescue ActionView::MissingTemplate => e
+ if resource && resource.respond_to?(:"to_#{format.to_sym}")
+ render options.merge(format.to_sym => resource)
+ else
+ raise e
end
end
+ end
+
+ # Collect mimes declared in the class method respond_to valid for the
+ # current action.
+ #
+ def collect_mimes_from_class_level #:nodoc:
+ action = action_name.to_sym
+
+ mimes_for_respond_to.keys.select do |mime|
+ config = mimes_for_respond_to[mime]
+
+ if config[:except]
+ !config[:except].include?(action)
+ elsif config[:only]
+ config[:only].include?(action)
+ else
+ true
+ end
+ end
+ end
+
+ class Responder #:nodoc:
+ attr_accessor :order
+
+ def initialize
+ @order, @responses = [], {}
+ end
def any(*args, &block)
if args.any?
args.each { |type| send(type, &block) }
else
- custom(@mime_type_priority.first, &block)
+ custom(Mime::ALL, &block)
end
end
-
+ alias :all :any
+
+ def custom(mime_type, &block)
+ mime_type = mime_type.is_a?(Mime::Type) ? mime_type : Mime::Type.lookup(mime_type.to_s)
+
+ @order << mime_type
+ @responses[mime_type] ||= block
+ end
+
+ def response_for(mime)
+ @responses[mime] || @responses[Mime::ALL]
+ end
+
def self.generate_method_for_mime(mime)
sym = mime.is_a?(Symbol) ? mime : mime.to_sym
const = sym.to_s.upcase
@@ -152,7 +339,7 @@ def #{sym}(&block) # def html(&block)
def method_missing(symbol, &block)
mime_constant = Mime.const_get(symbol.to_s.upcase)
-
+
if Mime::SET.include?(mime_constant)
self.class.generate_method_for_mime(mime_constant)
send(symbol, &block)
@@ -161,25 +348,6 @@ def method_missing(symbol, &block)
end
end
- def respond
- for priority in @mime_type_priority
- if priority == Mime::ALL
- @responses[@order.first].call
- return
- else
- if @responses[priority]
- @responses[priority].call
- return # mime type match found, be happy and return
- end
- end
- end
-
- if @order.include?(Mime::ALL)
- @responses[Mime::ALL].call
- else
- @controller.send :head, :not_acceptable
- end
- end
end
end
end
View
3 actionpack/lib/action_controller/base/renderer.rb
@@ -11,11 +11,10 @@ def process_action(*)
def render(options)
super
- options[:_template] ||= _action_view._partial
self.content_type ||= begin
mime = options[:_template].mime_type
formats.include?(mime && mime.to_sym) || formats.include?(:all) ? mime : Mime::Type.lookup_by_extension(formats.first)
- end
+ end.to_s
response_body
end
View
3 actionpack/lib/action_controller/base/request_forgery_protection.rb
@@ -106,8 +106,7 @@ def verifiable_request_format?
!request.content_type.nil? && request.content_type.verify_request?
end
- # Sets the token value for the current session. Pass a <tt>:secret</tt> option
- # in +protect_from_forgery+ to add a custom salt to the hash.
+ # Sets the token value for the current session.
def form_authenticity_token
session[:_csrf_token] ||= ActiveSupport::SecureRandom.base64(32)
end
View
2 actionpack/lib/action_controller/routing.rb
@@ -139,7 +139,7 @@ module ActionController
# # In routes.rb
# map.with_options :controller => 'blog' do |blog|
# blog.show '', :action => 'list'
- # blog.delete 'delete/:id', :action => 'delete',
+ # blog.delete 'delete/:id', :action => 'delete'
# blog.edit 'edit/:id', :action => 'edit'
# end
#
View
2 actionpack/lib/action_controller/routing/generation/url_rewriter.rb
@@ -93,7 +93,7 @@ def self.included(base) #:nodoc:
#
# * <tt>:only_path</tt> - If true, the relative url is returned. Defaults to +false+.
# * <tt>:protocol</tt> - The protocol to connect to. Defaults to 'http'.
- # * <tt>:host</tt> - Specifies the host the link should be targetted at.
+ # * <tt>:host</tt> - Specifies the host the link should be targeted at.
# If <tt>:only_path</tt> is false, this option must be
# provided either explicitly, or via +default_url_options+.
# * <tt>:port</tt> - Optionally specify the port to connect to.
View
2 actionpack/lib/action_controller/routing/route_set.rb
@@ -155,7 +155,7 @@ def #{selector}(options = nil) # def hash_f
def define_url_helper(route, name, kind, options)
selector = url_helper_name(name, kind)
- # The segment keys used for positional paramters
+ # The segment keys used for positional parameters
hash_access_method = hash_access_name(name, kind)
View
4 actionpack/lib/action_controller/testing/test_case.rb
@@ -56,7 +56,7 @@ module ActionController
#
# ActionController::TestCase will automatically infer the controller under test
# from the test class name. If the controller cannot be inferred from the test
- # class name, you can explicity set it with +tests+.
+ # class name, you can explicitly set it with +tests+.
#
# class SpecialEdgeCaseWidgetsControllerTest < ActionController::TestCase
# tests WidgetController
@@ -182,7 +182,7 @@ def setup_controller_request_and_response
@controller.send(:initialize_current_url)
end
end
-
+
# Cause the action to be rescued according to the regular rules for rescue_action when the visitor is not local
def rescue_action_in_public!
@request.remote_addr = '208.77.188.166' # example.com
View
2 actionpack/lib/action_dispatch/http/mime_type.rb
@@ -84,7 +84,7 @@ def lookup(string)
end
def lookup_by_extension(extension)
- EXTENSION_LOOKUP[extension]
+ EXTENSION_LOOKUP[extension.to_s]
end
# Registers an alias that's not used on mime type lookup, but can be referenced directly. Especially useful for
View
6 actionpack/lib/action_dispatch/http/mime_types.rb
@@ -2,7 +2,6 @@
# http://www.iana.org/assignments/media-types/
Mime::Type.register "text/html", :html, %w( application/xhtml+xml ), %w( xhtml )
-Mime::Type.register "*/*", :all
Mime::Type.register "text/plain", :text, [], %w(txt)
Mime::Type.register "text/javascript", :js, %w( application/javascript application/x-javascript )
Mime::Type.register "text/css", :css
@@ -18,4 +17,7 @@
# http://www.ietf.org/rfc/rfc4627.txt
# http://www.json.org/JSONRequest.html
-Mime::Type.register "application/json", :json, %w( text/x-json application/jsonrequest )
+Mime::Type.register "application/json", :json, %w( text/x-json application/jsonrequest )
+
+# Create Mime::ALL but do not add it to the SET.
+Mime::ALL = Mime::Type.new("*/*", :all, [])
View
42 actionpack/lib/action_dispatch/http/request.rb
@@ -161,7 +161,7 @@ def fresh?(response)
# GET /posts/5.xml | request.format => Mime::XML
# GET /posts/5.xhtml | request.format => Mime::HTML
# GET /posts/5 | request.format => Mime::HTML or MIME::JS, or request.accepts.first depending on the value of <tt>ActionController::Base.use_accept_header</tt>
-
+ #
def format(view_path = [])
@env["action_dispatch.request.format"] ||=
if parameters[:format]
@@ -173,21 +173,19 @@ def format(view_path = [])
end
end
+ # Expand raw_formats by converting Mime::ALL to the Mime::SET.
+ #
def formats
if ActionController::Base.use_accept_header
- if param = parameters[:format]
- Array.wrap(Mime[param])
- else
- accepts.dup
- end.tap do |ret|
+ raw_formats.tap do |ret|
if ret == ONLY_ALL
ret.replace Mime::SET
elsif all = ret.index(Mime::ALL)
ret.delete_at(all) && ret.insert(all, *Mime::SET)
end
end
else
- [format] + Mime::SET
+ raw_formats + Mime::SET
end
end
@@ -232,7 +230,7 @@ def cache_format
def xml_http_request?
!(@env['HTTP_X_REQUESTED_WITH'] !~ /XMLHttpRequest/i)
end
- alias xhr? :xml_http_request?
+ alias :xhr? :xml_http_request?
# Which IP addresses are "trusted proxies" that can be stripped from
# the right-hand-side of X-Forwarded-For
@@ -485,7 +483,35 @@ def flash
session['flash'] || {}
end
+ # Receives an array of mimes and return the first user sent mime that
+ # matches the order array.
+ #
+ def negotiate_mime(order)
+ raw_formats.each do |priority|
+ if priority == Mime::ALL
+ return order.first
+ elsif order.include?(priority)
+ return priority
+ end
+ end
+
+ order.include?(Mime::ALL) ? formats.first : nil
+ end
+
private
+
+ def raw_formats
+ if ActionController::Base.use_accept_header
+ if param = parameters[:format]
+ Array.wrap(Mime[param])
+ else
+ accepts.dup
+ end
+ else
+ [format]
+ end
+ end
+
def named_host?(host)
!(host.nil? || /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.match(host))
end
View
30 actionpack/lib/action_view/helpers/active_model_helper.rb
@@ -160,11 +160,24 @@ def error_message_on(object, method, *args)
#
# error_messages_for 'user'
#
+ # You can also supply an object:
+ #
+ # error_messages_for @user
+ #
+ # This will use the last part of the model name in the presentation. For instance, if
+ # this is a MyKlass::User object, this will use "user" as the name in the String. This
+ # is taken from MyKlass::User.model_name.human, which can be overridden.
+ #
# To specify more than one object, you simply list them; optionally, you can add an extra <tt>:object_name</tt> parameter, which
# will be the name used in the header message:
#
# error_messages_for 'user_common', 'user', :object_name => 'user'
#
+ # You can also use a number of objects, which will have the same naming semantics
+ # as a single object.
+ #
+ # error_messages_for @user, @post
+ #
# If the objects cannot be located as instance variables, you can add an extra <tt>:object</tt> parameter which gives the actual
# object (or array of objects to use):
#
@@ -176,15 +189,20 @@ def error_message_on(object, method, *args)
def error_messages_for(*params)
options = params.extract_options!.symbolize_keys
- if object = options.delete(:object)
- objects = [object].flatten
- else
- objects = params.collect {|object_name| instance_variable_get("@#{object_name}") }.compact
+ objects = Array.wrap(options.delete(:object) || params).map do |object|
+ unless object.respond_to?(:to_model)
+ object = instance_variable_get("@#{object}")
+ object = convert_to_model(object)
+ else
+ object = object.to_model
+ options[:object_name] ||= object.class.model_name.human
+ end
+ object
end
- objects.map! {|o| convert_to_model(o) }
+ objects.compact!
- count = objects.inject(0) {|sum, object| sum + object.errors.count }
+ count = objects.inject(0) {|sum, object| sum + object.errors.count }
unless count.zero?
html = {}
[:id, :class].each do |key|
View
2 actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -557,7 +557,7 @@ def image_tag(source, options = {})
# video_tag("trailer.ogg") # =>
# <video src="/videos/trailer.ogg" />
# video_tag("trailer.ogg", :controls => true, :autobuffer => true) # =>
- # <video autobuffer="true" controls="true" src="/videos/trailer.ogg" />
+ # <video autobuffer="autobuffer" controls="controls" src="/videos/trailer.ogg" />
# video_tag("trailer.m4v", :size => "16x10", :poster => "screenshot.png") # =>
# <video src="/videos/trailer.m4v" width="16" height="10" poster="/images/screenshot.png" />
# video_tag("/trailers/hd.avi", :size => "16x16") # =>
View
10 actionpack/lib/action_view/helpers/date_helper.rb
@@ -112,12 +112,12 @@ def time_ago_in_words(from_time, include_seconds = false)
# ==== Options
# * <tt>:use_month_numbers</tt> - Set to true if you want to use month numbers rather than month names (e.g.
# "2" instead of "February").
- # * <tt>:use_short_month</tt> - Set to true if you want to use the abbreviated month name instead of the full
- # name (e.g. "Feb" instead of "February").
- # * <tt>:add_month_number</tt> - Set to true if you want to show both, the month's number and name (e.g.
+ # * <tt>:use_short_month</tt> - Set to true if you want to use abbreviated month names instead of full
+ # month names (e.g. "Feb" instead of "February").
+ # * <tt>:add_month_numbers</tt> - Set to true if you want to use both month numbers and month names (e.g.
# "2 - February" instead of "February").
# * <tt>:use_month_names</tt> - Set to an array with 12 month names if you want to customize month names.
- # Note: You can also use Rails' new i18n functionality for this.
+ # Note: You can also use Rails' i18n functionality for this.
# * <tt>:date_separator</tt> - Specifies a string to separate the date fields. Default is "" (i.e. nothing).
# * <tt>:start_year</tt> - Set the start year for the year select. Default is <tt>Time.now.year - 5</tt>.
# * <tt>:end_year</tt> - Set the end year for the year select. Default is <tt>Time.now.year + 5</tt>.
@@ -128,7 +128,7 @@ def time_ago_in_words(from_time, include_seconds = false)
# as a hidden field instead of showing a select field. Also note that this implicitly sets :discard_day to true.
# * <tt>:discard_year</tt> - Set to true if you don't want to show a year select. This includes the year
# as a hidden field instead of showing a select field.
- # * <tt>:order</tt> - Set to an array containing <tt>:day</tt>, <tt>:month</tt> and <tt>:year</tt> do
+ # * <tt>:order</tt> - Set to an array containing <tt>:day</tt>, <tt>:month</tt> and <tt>:year</tt> to
# customize the order in which the select fields are shown. If you leave out any of the symbols, the respective
# select will not be shown (like when you set <tt>:discard_xxx => true</tt>. Defaults to the order defined in
# the respective locale (e.g. [:year, :month, :day] in the en locale that ships with Rails).
View
42 actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -167,31 +167,31 @@ def collection_select(object, method, collection, value_method, text_method, opt
#
# In addition to the <tt>:include_blank</tt> option documented above,
# this method also supports a <tt>:model</tt> option, which defaults
- # to TimeZone. This may be used by users to specify a different time
- # zone model object. (See +time_zone_options_for_select+ for more
- # information.)
+ # to ActiveSupport::TimeZone. This may be used by users to specify a
+ # different time zone model object. (See +time_zone_options_for_select+
+ # for more information.)
#
- # You can also supply an array of TimeZone objects
+ # You can also supply an array of ActiveSupport::TimeZone objects
# as +priority_zones+, so that they will be listed above the rest of the
- # (long) list. (You can use TimeZone.us_zones as a convenience for
- # obtaining a list of the US time zones, or a Regexp to select the zones
+ # (long) list. (You can use ActiveSupport::TimeZone.us_zones as a convenience
+ # for obtaining a list of the US time zones, or a Regexp to select the zones
# of your choice)
#
# Finally, this method supports a <tt>:default</tt> option, which selects
- # a default TimeZone if the object's time zone is +nil+.
+ # a default ActiveSupport::TimeZone if the object's time zone is +nil+.
#
# Examples:
# time_zone_select( "user", "time_zone", nil, :include_blank => true)
#
# time_zone_select( "user", "time_zone", nil, :default => "Pacific Time (US & Canada)" )
#
- # time_zone_select( "user", 'time_zone', TimeZone.us_zones, :default => "Pacific Time (US & Canada)")
+ # time_zone_select( "user", 'time_zone', ActiveSupport::TimeZone.us_zones, :default => "Pacific Time (US & Canada)")
#
- # time_zone_select( "user", 'time_zone', [ TimeZone['Alaska'], TimeZone['Hawaii'] ])
+ # time_zone_select( "user", 'time_zone', [ ActiveSupport::TimeZone['Alaska'], ActiveSupport::TimeZone['Hawaii'] ])
#
# time_zone_select( "user", 'time_zone', /Australia/)
#
- # time_zone_select( "user", "time_zone", TZInfo::Timezone.all.sort, :model => TZInfo::Timezone)
+ # time_zone_select( "user", "time_zone", ActiveSupport::Timezone.all.sort, :model => ActiveSupport::Timezone)
def time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {})
InstanceTag.new(object, method, self, options.delete(:object)).to_time_zone_select_tag(priority_zones, options, html_options)
end
@@ -393,20 +393,20 @@ def grouped_options_for_select(grouped_options, selected_key = nil, prompt = nil
end
# Returns a string of option tags for pretty much any time zone in the
- # world. Supply a TimeZone name as +selected+ to have it marked as the
- # selected option tag. You can also supply an array of TimeZone objects
- # as +priority_zones+, so that they will be listed above the rest of the
- # (long) list. (You can use TimeZone.us_zones as a convenience for
- # obtaining a list of the US time zones, or a Regexp to select the zones
- # of your choice)
+ # world. Supply a ActiveSupport::TimeZone name as +selected+ to have it
+ # marked as the selected option tag. You can also supply an array of
+ # ActiveSupport::TimeZone objects as +priority_zones+, so that they will
+ # be listed above the rest of the (long) list. (You can use
+ # ActiveSupport::TimeZone.us_zones as a convenience for obtaining a list
+ # of the US time zones, or a Regexp to select the zones of your choice)
#
# The +selected+ parameter must be either +nil+, or a string that names
- # a TimeZone.
+ # a ActiveSupport::TimeZone.
#
- # By default, +model+ is the TimeZone constant (which can be obtained
- # in Active Record as a value object). The only requirement is that the
- # +model+ parameter be an object that responds to +all+, and returns
- # an array of objects that represent time zones.
+ # By default, +model+ is the ActiveSupport::TimeZone constant (which can
+ # be obtained in Active Record as a value object). The only requirement
+ # is that the +model+ parameter be an object that responds to +all+, and
+ # returns an array of objects that represent time zones.
#
# NOTE: Only the option tags are returned, you have to wrap this call in
# a regular HTML select tag.
View
5 actionpack/lib/action_view/helpers/tag_helper.rb
@@ -8,7 +8,10 @@ module Helpers #:nodoc:
module TagHelper
include ERB::Util
- BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked).to_set
+ BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer
+ autoplay controls loop selected hidden scoped async
+ defer reversed ismap seemless muted required
+ autofocus novalidate formnovalidate open).to_set
BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map {|attr| attr.to_sym })
# Returns an empty HTML tag of type +name+ which by default is XHTML
View
4 actionpack/lib/action_view/helpers/text_helper.rb
@@ -436,7 +436,7 @@ def cycle(first_value, *values)
end
# Returns the current cycle string after a cycle has been started. Useful
- # for complex table highlighing or any other design need which requires
+ # for complex table highlighting or any other design need which requires
# the current cycle string in more than one place.
#
# ==== Example
@@ -544,7 +544,7 @@ def auto_link_urls(text, html_options = {})
left, right = $`, $'
# detect already linked URLs and URLs in the middle of a tag
if left =~ /<[^>]+$/ && right =~ /^[^>]*>/
- # do not change string; URL is alreay linked
+ # do not change string; URL is already linked
href
else
# don't include trailing punctuation character as part of the URL
View
97 actionpack/lib/action_view/helpers/url_helper.rb
@@ -12,11 +12,11 @@ module UrlHelper
# Returns the URL for the set of +options+ provided. This takes the
# same options as +url_for+ in Action Controller (see the
- # documentation for ActionController::Base#url_for). Note that by default
- # <tt>:only_path</tt> is <tt>true</tt> so you'll get the relative /controller/action
- # instead of the fully qualified URL like http://example.com/controller/action.
+ # documentation for <tt>ActionController::Base#url_for</tt>). Note that by default
+ # <tt>:only_path</tt> is <tt>true</tt> so you'll get the relative "/controller/action"
+ # instead of the fully qualified URL like "http://example.com/controller/action".
#
- # When called from a view, url_for returns an HTML escaped url. If you
+ # When called from a view, +url_for+ returns an HTML escaped url. If you
# need an unescaped url, pass <tt>:escape => false</tt> in the +options+.
#
# ==== Options
@@ -34,8 +34,8 @@ module UrlHelper
#
# If you instead of a hash pass a record (like an Active Record or Active Resource) as the options parameter,
# you'll trigger the named route for that record. The lookup will happen on the name of the class. So passing
- # a Workshop object will attempt to use the workshop_path route. If you have a nested route, such as
- # admin_workshop_path you'll have to call that explicitly (it's impossible for url_for to guess that route).
+ # a Workshop object will attempt to use the +workshop_path+ route. If you have a nested route, such as
+ # +admin_workshop_path+ you'll have to call that explicitly (it's impossible for +url_for+ to guess that route).
#
# ==== Examples
# <%= url_for(:action => 'index') %>
@@ -97,10 +97,10 @@ def url_for(options = {})
# Creates a link tag of the given +name+ using a URL created by the set
# of +options+. See the valid options in the documentation for
- # url_for. It's also possible to pass a string instead
+ # +url_for+. It's also possible to pass a string instead
# of an options hash to get a link tag that uses the value of the string as the
# href for the link, or use <tt>:back</tt> to link to the referrer - a JavaScript back
- # link will be used in place of a referrer if none exists. If nil is passed as
+ # link will be used in place of a referrer if none exists. If +nil+ is passed as
# a name, the link itself will become the name.
#
# ==== Signatures
@@ -117,27 +117,22 @@ def url_for(options = {})
# * <tt>:popup => true || array of window options</tt> - This will force the
# link to open in a popup window. By passing true, a default browser window
# will be opened with the URL. You can also specify an array of options
- # that are passed-thru to JavaScripts window.open method.
+ # that are passed to the <tt>window.open</tt> JavaScript call.
# * <tt>:method => symbol of HTTP verb</tt> - This modifier will dynamically
# create an HTML form and immediately submit the form for processing using
# the HTTP verb specified. Useful for having links perform a POST operation
# in dangerous actions like deleting a record (which search bots can follow
# while spidering your site). Supported verbs are <tt>:post</tt>, <tt>:delete</tt> and <tt>:put</tt>.
# Note that if the user has JavaScript disabled, the request will fall back
- # to using GET. If you are relying on the POST behavior, you should check
- # for it in your controller's action by using the request object's methods
- # for <tt>post?</tt>, <tt>delete?</tt> or <tt>put?</tt>.
+ # to using GET. If <tt>:href => '#'</tt> is used and the user has JavaScript
+ # disabled clicking the link will have no effect. If you are relying on the
+ # POST behavior, you should check for it in your controller's action by using
+ # the request object's methods for <tt>post?</tt>, <tt>delete?</tt> or <tt>put?</tt>.
# * The +html_options+ will accept a hash of html attributes for the link tag.
#
- # Note that if the user has JavaScript disabled, the request will fall back
- # to using GET. If <tt>:href => '#'</tt> is used and the user has JavaScript disabled
- # clicking the link will have no effect. If you are relying on the POST
- # behavior, your should check for it in your controller's action by using the
- # request object's methods for <tt>post?</tt>, <tt>delete?</tt> or <tt>put?</tt>.
- #
# You can mix and match the +html_options+ with the exception of
- # <tt>:popup</tt> and <tt>:method</tt> which will raise an ActionView::ActionViewError
- # exception.
+ # <tt>:popup</tt> and <tt>:method</tt> which will raise an
+ # <tt>ActionView::ActionViewError</tt> exception.
#
# ==== Examples
# Because it relies on +url_for+, +link_to+ supports both older-style controller/action/id arguments
@@ -170,9 +165,11 @@ def url_for(options = {})
# You can use a block as well if your link target is hard to fit into the name parameter. ERb example:
#
# <% link_to(@profile) do %>
- # <strong><%= @profile.name %></strong> -- <span>Check it out!!</span>
+ # <strong><%= @profile.name %></strong> -- <span>Check it out!</span>
# <% end %>
- # # => <a href="/profiles/1"><strong>David</strong> -- <span>Check it out!!</span></a>
+ # # => <a href="/profiles/1">
+ # <strong>David</strong> -- <span>Check it out!</span>
+ # </a>
#
# Classes and ids for CSS are easy to produce:
#
@@ -215,7 +212,9 @@ def url_for(options = {})
# # => <a href="/images/9" onclick="if (confirm('Are you sure?')) { var f = document.createElement('form');
# f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;
# var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method');
- # m.setAttribute('value', 'delete'); f.appendChild(m);f.submit(); };return false;">Delete Image</a>
+ # m.setAttribute('value', 'delete');var s = document.createElement('input'); s.setAttribute('type', 'hidden');
+ # s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', 'Q/ttlxPYZ6R77B+vZ1sBkhj21G2isO9dpE6UtOHBApg=');
+ # f.appendChild(s)f.appendChild(m);f.submit(); };return false;">Delete Image</a>
def link_to(*args, &block)
if block_given?
options = args.first || {}
@@ -246,21 +245,21 @@ def link_to(*args, &block)
# by the set of +options+. This is the safest method to ensure links that
# cause changes to your data are not triggered by search bots or accelerators.
# If the HTML button does not work with your layout, you can also consider
- # using the link_to method with the <tt>:method</tt> modifier as described in
- # the link_to documentation.
+ # using the +link_to+ method with the <tt>:method</tt> modifier as described in
+ # the +link_to+ documentation.
#
- # The generated FORM element has a class name of <tt>button-to</tt>
+ # The generated form element has a class name of <tt>button-to</tt>
# to allow styling of the form itself and its children. You can control
# the form submission and input element behavior using +html_options+.
# This method accepts the <tt>:method</tt> and <tt>:confirm</tt> modifiers
- # described in the link_to documentation. If no <tt>:method</tt> modifier
+ # described in the +link_to+ documentation. If no <tt>:method</tt> modifier
# is given, it will default to performing a POST operation. You can also
# disable the button by passing <tt>:disabled => true</tt> in +html_options+.
# If you are using RESTful routes, you can pass the <tt>:method</tt>
# to change the HTTP verb used to submit the form.
#
# ==== Options
- # The +options+ hash accepts the same options at url_for.
+ # The +options+ hash accepts the same options as url_for.
#
# There are a few special +html_options+:
# * <tt>:method</tt> - Specifies the anchor name to be appended to the path.
@@ -317,7 +316,7 @@ def button_to(name, options = {}, html_options = {})
# Creates a link tag of the given +name+ using a URL created by the set of
# +options+ unless the current request URI is the same as the links, in
# which case only the name is returned (or the given block is yielded, if
- # one exists). You can give link_to_unless_current a block which will
+ # one exists). You can give +link_to_unless_current+ a block which will
# specialize the default behavior (e.g., show a "Start Here" link rather
# than the link's text).
#
@@ -343,7 +342,7 @@ def button_to(name, options = {}, html_options = {})
# <li><a href="/controller/about">About Us</a></li>
# </ul>
#
- # The implicit block given to link_to_unless_current is evaluated if the current
+ # The implicit block given to +link_to_unless_current+ is evaluated if the current
# action is the action given. So, if we had a comments page and wanted to render a
# "Go Back" link instead of a link to the comments page, we could do something like this...
#
@@ -360,7 +359,7 @@ def link_to_unless_current(name, options = {}, html_options = {}, &block)
# +options+ unless +condition+ is true, in which case only the name is
# returned. To specialize the default behavior (i.e., show a login link rather
# than just the plaintext link text), you can pass a block that
- # accepts the name or the full argument list for link_to_unless.
+ # accepts the name or the full argument list for +link_to_unless+.
#
# ==== Examples
# <%= link_to_unless(@current_user.nil?, "Reply", { :action => "reply" }) %>
@@ -391,8 +390,8 @@ def link_to_unless(condition, name, options = {}, html_options = {}, &block)
# Creates a link tag of the given +name+ using a URL created by the set of
# +options+ if +condition+ is true, in which case only the name is
# returned. To specialize the default behavior, you can pass a block that
- # accepts the name or the full argument list for link_to_unless (see the examples
- # in link_to_unless).
+ # accepts the name or the full argument list for +link_to_unless+ (see the examples
+ # in +link_to_unless+).
#
# ==== Examples
# <%= link_to_if(@current_user.nil?, "Login", { :controller => "sessions", :action => "new" }) %>
@@ -416,27 +415,27 @@ def link_to_if(condition, name, options = {}, html_options = {}, &block)
# also used as the name of the link unless +name+ is specified. Additional
# HTML attributes for the link can be passed in +html_options+.
#
- # mail_to has several methods for hindering email harvesters and customizing
+ # +mail_to+ has several methods for hindering email harvesters and customizing
# the email itself by passing special keys to +html_options+.
#
# ==== Options
- # * <tt>:encode</tt> - This key will accept the strings "javascript" or "hex".
- # Passing "javascript" will dynamically create and encode the mailto: link then
+ # * <tt>:encode</tt> - This key will accept the strings "javascript" or "hex".
+ # Passing "javascript" will dynamically create and encode the mailto link then
# eval it into the DOM of the page. This method will not show the link on
# the page if the user has JavaScript disabled. Passing "hex" will hex
- # encode the +email_address+ before outputting the mailto: link.
- # * <tt>:replace_at</tt> - When the link +name+ isn't provided, the
+ # encode the +email_address+ before outputting the mailto link.
+ # * <tt>:replace_at</tt> - When the link +name+ isn't provided, the
# +email_address+ is used for the link label. You can use this option to
# obfuscate the +email_address+ by substituting the @ sign with the string
# given as the value.
- # * <tt>:replace_dot</tt> - When the link +name+ isn't provided, the
+ # * <tt>:replace_dot</tt> - When the link +name+ isn't provided, the
# +email_address+ is used for the link label. You can use this option to
# obfuscate the +email_address+ by substituting the . in the email with the
# string given as the value.
- # * <tt>:subject</tt> - Preset the subject line of the email.
+ # * <tt>:subject</tt> - Preset the subject line of the email.
# * <tt>:body</tt> - Preset the body of the email.
- # * <tt>:cc</tt> - Carbon Copy addition recipients on the email.
- # * <tt>:bcc</tt> - Blind Carbon Copy additional recipients on the email.
+ # * <tt>:cc</tt> - Carbon Copy addition recipients on the email.
+ # * <tt>:bcc</tt> - Blind Carbon Copy additional recipients on the email.
#
# ==== Examples
# mail_to "me@domain.com"
@@ -607,23 +606,23 @@ def method_javascript_function(method, url = '', href = nil)
submit_function << "f.submit();"
end
- # Processes the _html_options_ hash, converting the boolean
+ # Processes the +html_options+ hash, converting the boolean
# attributes from true/false form into the form required by
# HTML/XHTML. (An attribute is considered to be boolean if
- # its name is listed in the given _bool_attrs_ array.)
+ # its name is listed in the given +bool_attrs+ array.)
#
- # More specifically, for each boolean attribute in _html_options_
+ # More specifically, for each boolean attribute in +html_options+
# given as:
#
- # "attr" => bool_value
+ # "attr" => bool_value
#
- # if the associated _bool_value_ evaluates to true, it is
+ # if the associated +bool_value+ evaluates to true, it is
# replaced with the attribute's name; otherwise the attribute is
- # removed from the _html_options_ hash. (See the XHTML 1.0 spec,
+ # removed from the +html_options+ hash. (See the XHTML 1.0 spec,
# section 4.5 "Attribute Minimization" for more:
# http://www.w3.org/TR/xhtml1/#h-4.5)
#
- # Returns the updated _html_options_ hash, which is also modified
+ # Returns the updated +html_options+ hash, which is also modified
# in place.
#
# Example:
View
204 actionpack/test/controller/mime_responds_test.rb
@@ -86,6 +86,7 @@ def custom_constant_handling
type.mobile { render :text => "Mobile" }
end
ensure
+ Mime::SET.delete(:mobile)
Mime.module_eval { remove_const :MOBILE if const_defined?(:MOBILE) }
end
@@ -98,6 +99,7 @@ def custom_constant_handling_without_block
end
ensure
+ Mime::SET.delete(:mobile)
Mime.module_eval { remove_const :MOBILE if const_defined?(:MOBILE) }
end
@@ -132,6 +134,7 @@ def iphone_with_html_response_type
end
ensure
+ Mime::SET.delete(:iphone)
Mime.module_eval { remove_const :IPHONE if const_defined?(:IPHONE) }
end
@@ -145,6 +148,7 @@ def iphone_with_html_response_type_without_layout
end
ensure
+ Mime::SET.delete(:iphone)
Mime.module_eval { remove_const :IPHONE if const_defined?(:IPHONE) }
end
@@ -162,7 +166,7 @@ def set_layout
end
end
-class MimeControllerTest < ActionController::TestCase
+class RespondToControllerTest < ActionController::TestCase
tests RespondToController
def setup
@@ -436,10 +440,10 @@ def test_extension_synonyms
def test_render_action_for_html
@controller.instance_eval do
def render(*args)
- unless args.empty?
- @action = args.first[:action] || action_name
- end
- response.body = "#{@action} - #{@template.formats}"
+ @action = args.first[:action] unless args.empty?
+ @action ||= action_name
+
+ response.body = "#{@action} - #{formats}"
end
end
@@ -467,7 +471,185 @@ def test_format_with_custom_response_type_and_request_headers
end
end
+class RespondResource
+ undef_method :to_json
+
+ def to_xml
+ "XML"
+ end
+
+ def to_js
+ "JS"
+ end
+end
+
+class RespondWithController < ActionController::Base
+ respond_to :html, :json
+ respond_to :xml, :except => :using_defaults
+ respond_to :js, :only => :using_defaults
+
+ def using_defaults
+ respond_to do |format|
+ format.csv { render :text => "CSV" }
+ end
+ end
+
+ def using_defaults_with_type_list
+ respond_to(:js, :xml)
+ end
+
+ def using_resource
+ respond_with(RespondResource.new)
+ end
+
+ def using_resource_with_options
+ respond_with(RespondResource.new, :status => :unprocessable_entity) do |format|
+ format.js
+ end
+ end
+
+ def default_overwritten
+ respond_to do |format|
+ format.html { render :text => "HTML" }
+ end
+ end
+
+protected
+
+ def _render_js(js, options)
+ self.content_type ||= Mime::JS
+ self.response_body = js.respond_to?(:to_js) ? js.to_js : js
+ end
+end
+
+class InheritedRespondWithController < RespondWithController
+ clear_respond_to
+ respond_to :xml, :json
+
+ def index
+ respond_with(RespondResource.new) do |format|
+ format.json { render :text => "JSON" }
+ end
+ end
+end
+
+class RespondWithControllerTest < ActionController::TestCase
+ tests RespondWithController
+
+ def setup
+ super
+ ActionController::Base.use_accept_header = true
+ @request.host = "www.example.com"
+ end
+
+ def teardown
+ super
+ ActionController::Base.use_accept_header = false
+ end
+
+ def test_using_defaults
+ @request.accept = "*/*"
+ get :using_defaults
+ assert_equal "text/html", @response.content_type
+ assert_equal 'Hello world!', @response.body
+
+ @request.accept = "text/csv"
+ get :using_defaults
+ assert_equal "text/csv", @response.content_type
+ assert_equal "CSV", @response.body
+
+ @request.accept = "text/javascript"
+ get :using_defaults
+ assert_equal "text/javascript", @response.content_type
+ assert_equal '$("body").visualEffect("highlight");', @response.body
+ end
+
+ def test_using_defaults_with_type_list
+ @request.accept = "*/*"
+ get :using_defaults_with_type_list
+ assert_equal "text/javascript", @response.content_type
+ assert_equal '$("body").visualEffect("highlight");', @response.body
+
+ @request.accept = "application/xml"
+ get :using_defaults_with_type_list
+ assert_equal "application/xml", @response.content_type
+ assert_equal "<p>Hello world!</p>\n", @response.body
+ end
+
+ def test_using_resource
+ @request.accept = "text/html"
+ get :using_resource
+ assert_equal "text/html", @response.content_type
+ assert_equal "Hello world!", @response.body
+
+ @request.accept = "application/xml"
+ get :using_resource
+ assert_equal "application/xml", @response.content_type
+ assert_equal "XML", @response.body
+
+ @request.accept = "application/json"
+ assert_raise ActionView::MissingTemplate do
+ get :using_resource
+ end
+ end
+
+ def test_using_resource_with_options
+ @request.accept = "application/xml"
+ get :using_resource_with_options
+ assert_equal "application/xml", @response.content_type
+ assert_equal 422, @response.status
+ assert_equal "XML", @response.body
+
+ @request.accept = "text/javascript"
+ get :using_resource_with_options
+ assert_equal "text/javascript", @response.content_type
+ assert_equal 422, @response.status
+ assert_equal "JS", @response.body
+ end
+
+ def test_default_overwritten
+ get :default_overwritten
+ assert_equal "text/html", @response.content_type
+ assert_equal "HTML", @response.body
+ end
+
+ def test_clear_respond_to
+ @controller = InheritedRespondWithController.new
+ @request.accept = "text/html"
+ get :index
+ assert_equal 406, @response.status
+ end
+
+ def test_first_in_respond_to_has_higher_priority
+ @controller = InheritedRespondWithController.new
+ @request.accept = "*/*"
+ get :index
+ assert_equal "application/xml", @response.content_type
+ assert_equal "XML", @response.body
+ end
+
+ def test_not_acceptable
+ @request.accept = "application/xml"
+ get :using_defaults
+ assert_equal 406, @response.status
+
+ @request.accept = "text/html"
+ get :using_defaults_with_type_list
+ assert_equal 406, @response.status
+
+ @request.accept = "application/json"
+ get :using_defaults_with_type_list
+ assert_equal 406, @response.status
+
+ @request.accept = "text/javascript"
+ get :using_resource
+ assert_equal 406, @response.status
+ end
+end
+
class AbstractPostController < ActionController::Base
+ respond_to :html, :iphone
+
self.view_paths = File.dirname(__FILE__) + "/../fixtures/post_test/"
end
@@ -476,10 +658,7 @@ class PostController < AbstractPostController
around_filter :with_iphone
def index
- respond_to do |type|
- type.html
- type.iphone
- end
+ respond_to # It will use formats declared above
end
protected
@@ -489,17 +668,12 @@ def with_iphone
request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone"
yield
ensure
+ Mime::SET.delete(:iphone)
Mime.module_eval { remove_const :IPHONE if const_defined?(:IPHONE) }
end
end
class SuperPostController < PostController
- def index
- respond_to do |type|
- type.html
- type.iphone
- end
- end
end
class MimeControllerLayoutsTest < ActionController::TestCase
View
51 actionpack/test/dispatch/request_test.rb
@@ -338,16 +338,11 @@ def teardown
end
test "XMLHttpRequest" do
- begin
- ActionController::Base.use_accept_header, old =
- false, ActionController::Base.use_accept_header
-
+ with_accept_header false do
request = stub_request 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest'
request.expects(:parameters).at_least_once.returns({})
assert request.xhr?
assert_equal Mime::JS, request.format
- ensure
- ActionController::Base.use_accept_header = old
end
end
@@ -396,10 +391,54 @@ def teardown
assert_equal({"bar" => 2}, request.query_parameters)
end
+ test "formats with accept header" do
+ with_accept_header true do
+ request = stub_request 'HTTP_ACCEPT' => 'text/html'
+ request.expects(:parameters).at_least_once.returns({})
+ assert_equal [ Mime::HTML ], request.formats
+
+ request = stub_request 'CONTENT_TYPE' => 'application/xml; charset=UTF-8'
+ request.expects(:parameters).at_least_once.returns({})
+ assert_equal with_set(Mime::XML, Mime::HTML), request.formats
+ end
+
+ with_accept_header false do
+ request = stub_request
+ request.expects(:parameters).at_least_once.returns({ :format => :txt })
+ assert_equal with_set(Mime::TEXT), request.formats
+ end
+ end
+
+ test "negotiate_mime" do
+ with_accept_header true do
+ request = stub_request 'HTTP_ACCEPT' => 'text/html'
+ request.expects(:parameters).at_least_once.returns({})
+
+ assert_equal nil, request.negotiate_mime([Mime::XML, Mime::JSON])
+ assert_equal Mime::HTML, request.negotiate_mime([Mime::XML, Mime::HTML])
+ assert_equal Mime::HTML, request.negotiate_mime([Mime::XML, Mime::ALL])
+
+ request = stub_request 'CONTENT_TYPE' => 'application/xml; charset=UTF-8'
+ request.expects(:parameters).at_least_once.returns({})
+ assert_equal Mime::XML, request.negotiate_mime([Mime::XML, Mime::CSV])
+ assert_equal Mime::CSV, request.negotiate_mime([Mime::CSV, Mime::YAML])
+ end
+ end
+
protected
def stub_request(env={})
ActionDispatch::Request.new(env)
end
+ def with_set(*args)
+ args + Mime::SET
+ end
+
+ def with_accept_header(value)
+ ActionController::Base.use_accept_header, old = value, ActionController::Base.use_accept_header
+ yield
+ ensure
+ ActionController::Base.use_accept_header = old
+ end
end
View
2 actionpack/test/fixtures/public/.gitignore
@@ -1 +1 @@
-absolute
+absolute/*
View
1 actionpack/test/fixtures/respond_with/using_defaults.html.erb
@@ -0,0 +1 @@
+Hello world!
View
1 actionpack/test/fixtures/respond_with/using_defaults.js.rjs
@@ -0,0 +1 @@
+page[:body].visual_effect :highlight
View
1 actionpack/test/fixtures/respond_with/using_defaults_with_type_list.js.rjs
@@ -0,0 +1 @@
+page[:body].visual_effect :highlight
View
1 actionpack/test/fixtures/respond_with/using_defaults_with_type_list.xml.builder
@@ -0,0 +1 @@
+xml.p "Hello world!"
View
1 actionpack/test/fixtures/respond_with/using_resource.html.erb
@@ -0,0 +1 @@
+Hello world!
View
7 actionpack/test/template/active_record_helper_i18n_test.rb
@@ -3,11 +3,14 @@
class ActiveRecordHelperI18nTest < Test::Unit::TestCase
include ActionView::Context
include ActionView::Helpers::ActiveModelHelper
-
+
attr_reader :request
def setup
@object = stub :errors => stub(:count => 1, :full_messages => ['full_messages'])
+ @object.stubs :to_model => @object
+ @object.stubs :class => stub(:model_name => stub(:human => ""))
+
@object_name = 'book_seller'
@object_name_without_underscore = 'book seller'
@@ -39,7 +42,7 @@ def test_error_messages_for_given_no_message_option_it_translates_message
I18n.expects(:t).with('', :default => '', :count => 1, :scope => [:activerecord, :models]).once.returns ''
error_messages_for(:object => @object, :locale => 'en')
end
-
+
def test_error_messages_for_given_object_name_it_translates_object_name
I18n.expects(:t).with(:header, :locale => 'en', :scope => [:activerecord, :errors, :template], :count => 1, :model => @object_name_without_underscore).returns "1 error prohibited this #{@object_name_without_underscore} from being saved"
I18n.expects(:t).with(@object_name, :default => @object_name_without_underscore, :count => 1, :scope => [:activerecord, :models]).once.returns @object_name_without_underscore
View
10 actionpack/test/template/active_record_helper_test.rb
@@ -295,6 +295,16 @@ def test_error_messages_for_non_instance_variable
assert_equal '', error_messages_for('user', :object => nil)
end
+ def test_error_messages_for_model_objects
+ error = error_messages_for(@post)
+ assert_dom_equal %(<div class="errorExplanation" id="errorExplanation"><h2>1 error prohibited this post from being saved</h2><p>There were problems with the following fields:</p><ul><li>Author name can't be empty</li></ul></div>),
+ error
+
+ error = error_messages_for(@user, @post)
+ assert_dom_equal %(<div class="errorExplanation" id="errorExplanation"><h2>2 errors prohibited this user from being saved</h2><p>There were problems with the following fields:</p><ul><li>User email can't be empty</li><li>Author name can't be empty</li></ul></div>),
+ error
+ end
+
def test_form_with_string_multipart
assert_dom_equal(
%(<form action="create" enctype="multipart/form-data" method="post"><p><label for="post_title">Title</label><br /><input id="post_title" name="post[title]" size="30" type="text" value="Hello World" /></p>\n<p><label for="post_body">Body</label><br /><div class="fieldWithErrors"><textarea cols="40" id="post_body" name="post[body]" rows="20">Back to the hill and over it again!</textarea></div></p><input name="commit" type="submit" value="Create" /></form>),
View
8 actionpack/test/template/asset_tag_helper_test.rb
@@ -158,8 +158,8 @@ def teardown
VideoLinkToTag = {
%(video_tag("xml.ogg")) => %(<video src="/videos/xml.ogg" />),
- %(video_tag("rss.m4v", :autoplay => true, :controls => true)) => %(<video autoplay="true" controls="true" src="/videos/rss.m4v" />),
- %(video_tag("rss.m4v", :autobuffer => true)) => %(<video autobuffer="true" src="/videos/rss.m4v" />),
+ %(video_tag("rss.m4v", :autoplay => true, :controls => true)) => %(<video autoplay="autoplay" controls="controls" src="/videos/rss.m4v" />),
+ %(video_tag("rss.m4v", :autobuffer => true)) => %(<video autobuffer="autobuffer" src="/videos/rss.m4v" />),
%(video_tag("gold.m4v", :size => "160x120")) => %(<video height="120" src="/videos/gold.m4v" width="160" />),
%(video_tag("gold.m4v", "size" => "320x240")) => %(<video height="240" src="/videos/gold.m4v" width="320" />),
%(video_tag("trailer.ogg", :poster => "screenshot.png")) => %(<video poster="/images/screenshot.png" src="/videos/trailer.ogg" />),
@@ -168,7 +168,7 @@ def teardown
%(video_tag("error.avi", "size" => "x")) => %(<video src="/videos/error.avi" />),
%(video_tag("http://media.rubyonrails.org/video/rails_blog_2.mov")) => %(<video src="http://media.rubyonrails.org/video/rails_blog_2.mov" />),
%(video_tag(["multiple.ogg", "multiple.avi"])) => %(<video><source src="multiple.ogg" /><source src="multiple.avi" /></video>),
- %(video_tag(["multiple.ogg", "multiple.avi"], :size => "160x120", :controls => true)) => %(<video controls="true" height="120" width="160"><source src="multiple.ogg" /><source src="multiple.avi" /></video>)
+ %(video_tag(["multiple.ogg", "multiple.avi"], :size => "160x120", :controls => true)) => %(<video controls="controls" height="120" width="160"><source src="multiple.ogg" /><source src="multiple.avi" /></video>)
}
AudioPathToTag = {
@@ -187,7 +187,7 @@ def teardown
AudioLinkToTag = {
%(audio_tag("xml.wav")) => %(<audio src="/audios/xml.wav" />),
- %(audio_tag("rss.wav", :autoplay => true, :controls => true)) => %(<audio autoplay="true" controls="true" src="/audios/rss.wav" />),
+ %(audio_tag("rss.wav", :autoplay => true, :controls => true)) => %(<audio autoplay="autoplay" controls="controls" src="/audios/rss.wav" />),
%(audio_tag("http://media.rubyonrails.org/audio/rails_blog_2.mov")) => %(<audio src="http://media.rubyonrails.org/audio/rails_blog_2.mov" />),
}
View
3 activemodel/lib/active_model/naming.rb
@@ -2,14 +2,15 @@
module ActiveModel
class Name < String
- attr_reader :singular, :plural, :element, :collection, :partial_path
+ attr_reader :singular, :plural, :element, :collection, :partial_path, :human
alias_method :cache_key, :collection
def initialize(name)
super
@singular = ActiveSupport::Inflector.underscore(self).tr('/', '_').freeze
@plural = ActiveSupport::Inflector.pluralize(@singular).freeze
@element = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(self)).freeze
+ @human = @element.gsub(/_/, " ")
@collection = ActiveSupport::Inflector.tableize(self).freeze
@partial_path = "#{@collection}/#{@element}".freeze
end
View
8 activemodel/lib/active_model/serializers/xml.rb
@@ -90,7 +90,7 @@ def builder
end
def root
- root = (options[:root] || @serializable.class.to_s.underscore).to_s
+ root = (options[:root] || @serializable.class.model_name.singular).to_s
reformat_name(root)
end
@@ -152,7 +152,11 @@ def add_attributes
def add_procs
if procs = options.delete(:procs)
[ *procs ].each do |proc|
- proc.call(options)
+ if proc.arity > 1
+ proc.call(options, @serializable)
+ else
+ proc.call(options)
+ end
end
end
end
View
23 activemodel/test/cases/serializeration/xml_serialization_test.rb
@@ -9,6 +9,11 @@ def attributes
end
end
+module Admin
+ class Contact < ::Contact
+ end
+end