Skip to content
Browse files

Merge commit 'rails/master'

  • Loading branch information...
2 parents 0489f0c + 181cd10 commit 24260dc0c8338aef8e24407e00750fd72a0366ea @miloops miloops committed Sep 14, 2009
Showing with 1,223 additions and 673 deletions.
  1. +2 −0 .gitignore
  2. +0 −1 actionmailer/lib/actionmailer.rb
  3. +14 −0 actionpack/Gemfile
  4. +15 −28 actionpack/Rakefile
  5. +20 −2 actionpack/lib/action_controller/metal.rb
  6. +1 −1 actionpack/lib/action_controller/metal/filter_parameter_logging.rb
  7. +0 −1 actionpack/lib/action_controller/testing/integration.rb
  8. +35 −40 actionpack/lib/action_dispatch/middleware/session/mem_cache_store.rb
  9. +1 −0 actionpack/lib/action_view/helpers/asset_tag_helper.rb
  10. +19 −7 actionpack/lib/action_view/helpers/form_helper.rb
  11. +1 −0 actionpack/lib/action_view/helpers/url_helper.rb
  12. +1 −1 actionpack/lib/action_view/template/handlers/builder.rb
  13. +0 −1 actionpack/lib/actionpack.rb
  14. +1 −1 actionpack/test/abstract_controller/abstract_controller_test.rb
  15. +2 −2 actionpack/test/abstract_controller/callbacks_test.rb
  16. +1 −1 actionpack/test/abstract_controller/helper_test.rb
  17. +1 −1 actionpack/test/abstract_controller/layouts_test.rb
  18. +0 −21 actionpack/test/abstract_controller/test_helper.rb
  19. +4 −5 actionpack/test/abstract_unit.rb
  20. +10 −5 actionpack/test/{new_base/test_helper.rb → abstract_unit2.rb}
  21. +3 −3 actionpack/test/{lib → }/active_record_unit.rb
  22. +10 −0 actionpack/test/bundler_helper.rb
  23. +1 −0 actionpack/test/controller/filter_params_test.rb
  24. +1 −0 actionpack/test/controller/rescue_test.rb
  25. +3 −2 actionpack/test/controller/resources_test.rb
  26. +1 −0 actionpack/test/lib/controller/fake_controllers.rb
  27. +2 −2 actionpack/test/new_base/base_test.rb
  28. +2 −2 actionpack/test/new_base/content_negotiation_test.rb
  29. +1 −1 actionpack/test/new_base/content_type_test.rb
  30. +2 −2 actionpack/test/new_base/etag_test.rb
  31. +1 −2 actionpack/test/new_base/metal_test.rb
  32. +77 −0 actionpack/test/new_base/middleware_test.rb
  33. +0 −1 actionpack/test/new_base/redirect_test.rb
  34. +2 −2 actionpack/test/new_base/render_action_test.rb
  35. +2 −2 actionpack/test/new_base/render_file_test.rb
  36. +2 −2 actionpack/test/new_base/render_implicit_action_test.rb
  37. +2 −2 actionpack/test/new_base/render_layout_test.rb
  38. +2 −2 actionpack/test/new_base/render_partial_test.rb
  39. +2 −2 actionpack/test/new_base/render_rjs_test.rb
  40. +2 −2 actionpack/test/new_base/render_template_test.rb
  41. +2 −2 actionpack/test/new_base/render_test.rb
  42. +2 −2 actionpack/test/new_base/render_text_test.rb
  43. +2 −2 actionpack/test/new_base/render_xml_test.rb
  44. +0 −46 actionpack/test/old_base/abstract_unit.rb
  45. +0 −8 actionpack/test/runner
  46. +36 −0 actionpack/test/template/form_helper_test.rb
  47. +1 −1 actionpack/test/template/form_options_helper_test.rb
  48. +1 −0 actionpack/test/template/url_helper_test.rb
  49. +2 −1 activemodel/lib/active_model/errors.rb
  50. +0 −1 activemodel/lib/activemodel.rb
  51. +16 −0 activemodel/test/cases/validations_test.rb
  52. +4 −3 activerecord/lib/active_record/associations.rb
  53. +2 −2 activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
  54. +31 −21 activerecord/lib/active_record/autosave_association.rb
  55. +2 −1 activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
  56. +0 −22 activerecord/lib/active_record/locking/pessimistic.rb
  57. +38 −22 activerecord/lib/active_record/nested_attributes.rb
  58. +0 −1 activerecord/lib/activerecord.rb
  59. +9 −0 activerecord/test/cases/associations/has_one_associations_test.rb
  60. +220 −1 activerecord/test/cases/autosave_association_test.rb
  61. +47 −33 activerecord/test/cases/nested_attributes_test.rb
  62. +3 −3 activerecord/test/cases/reflection_test.rb
  63. +6 −3 activerecord/test/cases/validations_test.rb
  64. +1 −0 activerecord/test/fixtures/accounts.yml
  65. +6 −0 activerecord/test/models/company.rb
  66. +6 −3 activerecord/test/models/pirate.rb
  67. +1 −1 activerecord/test/models/ship.rb
  68. +2 −0 activerecord/test/models/treasure.rb
  69. +1 −0 activerecord/test/schema/schema.rb
  70. +0 −1 activeresource/lib/activeresource.rb
  71. +1 −0 activesupport/lib/active_support.rb
  72. +1 −1 activesupport/lib/active_support/cache/mem_cache_store.rb
  73. +1 −1 activesupport/lib/active_support/core_ext/array/conversions.rb
  74. +1 −1 activesupport/lib/active_support/core_ext/hash/conversions.rb
  75. +4 −2 activesupport/lib/active_support/core_ext/rexml.rb
  76. +1 −1 activesupport/lib/active_support/core_ext/string/xchar.rb
  77. +2 −3 activesupport/lib/active_support/json/backends/jsongem.rb
  78. +1 −5 activesupport/lib/active_support/json/backends/yaml.rb
  79. +2 −0 activesupport/lib/active_support/json/decoding.rb
  80. +8 −28 activesupport/lib/active_support/message_verifier.rb
  81. +4 −4 activesupport/lib/active_support/multibyte/utils.rb
  82. +5 −2 activesupport/lib/active_support/new_callbacks.rb
  83. +0 −1 activesupport/lib/active_support/test_case.rb
  84. +0 −2 activesupport/lib/active_support/testing/performance.rb
  85. +1 −1 activesupport/lib/active_support/values/time_zone.rb
  86. +19 −23 activesupport/lib/active_support/vendor.rb
  87. 0 activesupport/lib/active_support/vendor/builder-2.1.2/{ → lib}/blankslate.rb
  88. 0 activesupport/lib/active_support/vendor/builder-2.1.2/{ → lib}/builder.rb
  89. 0 activesupport/lib/active_support/vendor/builder-2.1.2/{ → lib}/builder/blankslate.rb
  90. 0 activesupport/lib/active_support/vendor/builder-2.1.2/{ → lib}/builder/css.rb
  91. 0 activesupport/lib/active_support/vendor/builder-2.1.2/{ → lib}/builder/xchar.rb
  92. 0 activesupport/lib/active_support/vendor/builder-2.1.2/{ → lib}/builder/xmlbase.rb
  93. 0 activesupport/lib/active_support/vendor/builder-2.1.2/{ → lib}/builder/xmlevents.rb
  94. 0 activesupport/lib/active_support/vendor/builder-2.1.2/{ → lib}/builder/xmlmarkup.rb
  95. +6 −0 activesupport/lib/active_support/vendor/builder.rb
  96. +6 −0 activesupport/lib/active_support/vendor/i18n.rb
  97. +291 −93 ...support/lib/active_support/vendor/{memcache-client-1.6.5 → memcache-client-1.7.5/lib}/memcache.rb
  98. +6 −0 activesupport/lib/active_support/vendor/memcache.rb
  99. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo.rb
  100. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/data_timezone.rb
  101. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/data_timezone_info.rb
  102. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Africa/Algiers.rb
  103. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Africa/Cairo.rb
  104. 0 ...esupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Africa/Casablanca.rb
  105. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Africa/Harare.rb
  106. 0 ...upport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Africa/Johannesburg.rb
  107. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Africa/Monrovia.rb
  108. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Africa/Nairobi.rb
  109. 0 ...active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Argentina/Buenos_Aires.rb
  110. 0 ...lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Argentina/San_Juan.rb
  111. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Bogota.rb
  112. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Caracas.rb
  113. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Chicago.rb
  114. 0 ...esupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Chihuahua.rb
  115. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Denver.rb
  116. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Godthab.rb
  117. 0 ...esupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Guatemala.rb
  118. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Halifax.rb
  119. 0 ...b/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Indiana/Indianapolis.rb
  120. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Juneau.rb
  121. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/La_Paz.rb
  122. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Lima.rb
  123. 0 ...upport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Los_Angeles.rb
  124. 0 ...vesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Mazatlan.rb
  125. 0 ...upport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Mexico_City.rb
  126. 0 ...esupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Monterrey.rb
  127. 0 ...vesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/New_York.rb
  128. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Phoenix.rb
  129. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Regina.rb
  130. 0 ...vesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Santiago.rb
  131. 0 ...esupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Sao_Paulo.rb
  132. 0 ...vesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/St_Johns.rb
  133. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/America/Tijuana.rb
  134. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Almaty.rb
  135. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Baghdad.rb
  136. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Baku.rb
  137. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Bangkok.rb
  138. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Chongqing.rb
  139. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Colombo.rb
  140. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Dhaka.rb
  141. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Hong_Kong.rb
  142. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Irkutsk.rb
  143. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Jakarta.rb
  144. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Jerusalem.rb
  145. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Kabul.rb
  146. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Kamchatka.rb
  147. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Karachi.rb
  148. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Kathmandu.rb
  149. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Kolkata.rb
  150. 0 ...vesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Krasnoyarsk.rb
  151. 0 ...esupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Kuala_Lumpur.rb
  152. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Kuwait.rb
  153. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Magadan.rb
  154. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Muscat.rb
  155. 0 ...vesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Novosibirsk.rb
  156. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Rangoon.rb
  157. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Riyadh.rb
  158. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Seoul.rb
  159. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Shanghai.rb
  160. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Singapore.rb
  161. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Taipei.rb
  162. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Tashkent.rb
  163. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Tbilisi.rb
  164. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Tehran.rb
  165. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Tokyo.rb
  166. 0 ...vesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Ulaanbaatar.rb
  167. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Urumqi.rb
  168. 0 ...vesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Vladivostok.rb
  169. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Yakutsk.rb
  170. 0 ...support/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Yekaterinburg.rb
  171. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Asia/Yerevan.rb
  172. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Atlantic/Azores.rb
  173. 0 ...upport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Atlantic/Cape_Verde.rb
  174. 0 ...ort/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Atlantic/South_Georgia.rb
  175. 0 ...support/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Australia/Adelaide.rb
  176. 0 ...support/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Australia/Brisbane.rb
  177. 0 ...vesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Australia/Darwin.rb
  178. 0 ...vesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Australia/Hobart.rb
  179. 0 ...upport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Australia/Melbourne.rb
  180. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Australia/Perth.rb
  181. 0 ...vesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Australia/Sydney.rb
  182. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Etc/UTC.rb
  183. 0 ...vesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Amsterdam.rb
  184. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Athens.rb
  185. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Belgrade.rb
  186. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Berlin.rb
  187. 0 ...esupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Bratislava.rb
  188. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Brussels.rb
  189. 0 ...vesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Bucharest.rb
  190. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Budapest.rb
  191. 0 ...esupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Copenhagen.rb
  192. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Dublin.rb
  193. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Helsinki.rb
  194. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Istanbul.rb
  195. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Kiev.rb
  196. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Lisbon.rb
  197. 0 ...vesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Ljubljana.rb
  198. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/London.rb
  199. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Madrid.rb
  200. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Minsk.rb
  201. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Moscow.rb
  202. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Paris.rb
  203. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Prague.rb
  204. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Riga.rb
  205. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Rome.rb
  206. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Sarajevo.rb
  207. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Skopje.rb
  208. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Sofia.rb
  209. 0 ...vesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Stockholm.rb
  210. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Tallinn.rb
  211. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Vienna.rb
  212. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Vilnius.rb
  213. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Warsaw.rb
  214. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Europe/Zagreb.rb
  215. 0 ...vesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Pacific/Auckland.rb
  216. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Pacific/Fiji.rb
  217. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Pacific/Guam.rb
  218. 0 ...vesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Pacific/Honolulu.rb
  219. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Pacific/Majuro.rb
  220. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Pacific/Midway.rb
  221. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Pacific/Noumea.rb
  222. 0 ...esupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Pacific/Pago_Pago.rb
  223. 0 ...pport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Pacific/Port_Moresby.rb
  224. 0 ...esupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/definitions/Pacific/Tongatapu.rb
  225. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/info_timezone.rb
  226. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/linked_timezone.rb
  227. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/linked_timezone_info.rb
  228. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/offset_rationals.rb
  229. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/ruby_core_support.rb
  230. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/time_or_datetime.rb
  231. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/timezone.rb
  232. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/timezone_definition.rb
  233. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/timezone_info.rb
  234. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/timezone_offset_info.rb
  235. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/timezone_period.rb
  236. 0 activesupport/lib/active_support/vendor/tzinfo-0.3.13/{ → lib}/tzinfo/timezone_transition_info.rb
  237. +6 −0 activesupport/lib/active_support/vendor/tzinfo.rb
  238. +2 −1 activesupport/lib/active_support/xml_mini/rexml.rb
  239. +0 −1 activesupport/lib/activesupport.rb
  240. +9 −2 activesupport/test/abstract_unit.rb
  241. +6 −2 activesupport/test/core_ext/string_ext_test.rb
  242. +2 −3 activesupport/test/flush_cache_on_private_memoization_test.rb
  243. +126 −122 activesupport/test/isolation_test.rb
  244. +2 −8 activesupport/test/json/decoding_test.rb
  245. +0 −10 activesupport/test/memoizable_test.rb
  246. +1 −1 activesupport/test/multibyte_chars_test.rb
  247. +10 −14 activesupport/test/multibyte_utils_test.rb
  248. +2 −4 activesupport/test/xml_mini/nokogiri_engine_test.rb
  249. +1 −1 railties/lib/commands/plugin.rb
  250. +9 −9 railties/lib/initializer.rb
View
2 .gitignore
@@ -27,3 +27,5 @@ railties/guides/output
*.rbc
*.swp
*.swo
+actionpack/bin
+*/vendor/gems
View
1 actionmailer/lib/actionmailer.rb
@@ -1 +0,0 @@
-require 'action_mailer'
View
14 actionpack/Gemfile
@@ -0,0 +1,14 @@
+rails_root = Pathname.new(File.dirname(__FILE__)).join("..")
+
+gem "rack", "~> 1.0.0"
+gem "rack-test", "~> 0.4.2"
+gem "activesupport", "3.0.pre", :vendored_at => rails_root.join("activesupport")
+gem "activemodel", "3.0.pre", :vendored_at => rails_root.join("activemodel")
+
+only :test do
+ gem "mocha"
+ gem "sqlite3-ruby"
+ gem "RedCloth"
+end
+
+disable_system_gems
View
43 actionpack/Rakefile
@@ -17,18 +17,25 @@ RUBY_FORGE_PROJECT = "actionpack"
RUBY_FORGE_USER = "webster132"
desc "Default Task"
-task :default => [ :test ]
+task :default => :test
+
+task :bundle do
+ puts "Checking if the bundled testing requirements are up to date..."
+ result = system "gem bundle"
+ unless result
+ puts "The gem bundler is not installed. Installing."
+ system "gem install bundler"
+ system "gem bundle"
+ end
+end
# Run the unit tests
desc "Run all unit tests"
task :test => [:test_action_pack, :test_active_record_integration, :test_new_base]
-test_lib_dirs = ENV["NEW"] ? ["test/new_base"] : []
-test_lib_dirs.push "test", "test/lib"
-# test_lib_dirs = [ENV["NEW"] ? "test/new_base" : "test", "test/lib"]
Rake::TestTask.new(:test_action_pack) do |t|
- t.libs.concat test_lib_dirs
+ t.libs << 'test'
# make sure we include the tests in alphabetical order as on some systems
# this will not happen automatically and the tests (as a whole) will error
@@ -41,44 +48,24 @@ end
task :isolated_test do
ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
Dir.glob("test/{controller,dispatch,template}/**/*_test.rb").all? do |file|
- system(ruby, "-Ilib:#{test_lib_dirs * ':'}", file)
+ system(ruby, "-Itest", file)
end or raise "Failures"
end
desc 'ActiveRecord Integration Tests'
Rake::TestTask.new(:test_active_record_integration) do |t|
- t.libs.concat test_lib_dirs
+ t.libs << 'test'
t.test_files = Dir.glob("test/activerecord/*_test.rb")
t.verbose = true
end
desc 'New Controller Tests'
Rake::TestTask.new(:test_new_base) do |t|
- t.libs << "test/new_base" << "test/lib"
+ t.libs << 'test'
t.test_files = Dir.glob("test/{abstract_controller,new_base}/*_test.rb")
t.verbose = true
end
-desc 'Old Controller Tests on New Base'
-Rake::TestTask.new(:test_new_base_on_old_tests) do |t|
- t.libs << "test/new_base" << "test/lib"
-
- t.verbose = true
- # ==== Not ported
- # * filters
-
- t.test_files = Dir.glob( "test/{dispatch,template}/**/*_test.rb" ).sort + %w(
- action_pack_assertions addresses_render assert_select
- base benchmark caching capture content_type cookie dispatcher
- filter_params flash helper http_basic_authentication
- http_digest_authentication integration layout logging mime_responds
- record_identifier redirect render render_js render_json
- render_other render_xml request_forgery_protection rescue
- resources routing selector send_file test url_rewriter
- verification view_paths webservice
- ).map { |name| "test/controller/#{name}_test.rb" }
-end
-
# Genereate the RDoc documentation
Rake::RDocTask.new { |rdoc|
View
22 actionpack/lib/action_controller/metal.rb
@@ -79,6 +79,15 @@ def to_a
end
class ActionEndpoint
+ @@endpoints = Hash.new {|h,k| h[k] = Hash.new {|h,k| h[k] = {} } }
+
+ def self.for(controller, action, stack)
+ @@endpoints[controller][action][stack] ||= begin
+ endpoint = new(controller, action)
+ stack.build(endpoint)
+ end
+ end
+
def initialize(controller, action)
@controller, @action = controller, action
end
@@ -88,6 +97,16 @@ def call(env)
end
end
+ extlib_inheritable_accessor(:middleware_stack) { ActionDispatch::MiddlewareStack.new }
+
+ def self.use(*args)
+ middleware_stack.use(*args)
+ end
+
+ def self.middleware
+ middleware_stack
+ end
+
# Return a rack endpoint for the given action. Memoize the endpoint, so
# multiple calls into MyController.action will return the same object
# for the same action.
@@ -98,8 +117,7 @@ def call(env)
# ==== Returns
# Proc:: A rack application
def self.action(name)
- @actions ||= {}
- @actions[name.to_s] ||= ActionEndpoint.new(self, name)
+ ActionEndpoint.for(self, name, middleware_stack)
end
end
end
View
2 actionpack/lib/action_controller/metal/filter_parameter_logging.rb
@@ -49,7 +49,7 @@ def filter_parameter_logging(*filter_words, &block)
end
elsif block_given?
key = key.dup
- value = value.dup if value
+ value = value.dup if value.duplicable?
yield key, value
filtered_parameters[key] = value
else
View
1 actionpack/lib/action_controller/testing/integration.rb
@@ -259,7 +259,6 @@ def process(method, path, parameters = nil, rack_environment = nil)
"rack.url_scheme" => https? ? "https" : "http",
"REQUEST_URI" => path,
- "PATH_INFO" => path,
"HTTP_HOST" => host,
"REMOTE_ADDR" => remote_addr,
"CONTENT_TYPE" => "application/x-www-form-urlencoded",
View
75 actionpack/lib/action_dispatch/middleware/session/mem_cache_store.rb
@@ -1,52 +1,47 @@
-require "active_support/core_ext/kernel/requires"
-begin
- require_library_or_gem 'memcache'
+module ActionDispatch
+ module Session
+ class MemCacheStore < AbstractStore
+ def initialize(app, options = {})
+ require 'memcache'
- module ActionDispatch
- module Session
- class MemCacheStore < AbstractStore
- def initialize(app, options = {})
- # Support old :expires option
- options[:expire_after] ||= options[:expires]
+ # Support old :expires option
+ options[:expire_after] ||= options[:expires]
- super
+ super
- @default_options = {
- :namespace => 'rack:session',
- :memcache_server => 'localhost:11211'
- }.merge(@default_options)
+ @default_options = {
+ :namespace => 'rack:session',
+ :memcache_server => 'localhost:11211'
+ }.merge(@default_options)
- @pool = options[:cache] || MemCache.new(@default_options[:memcache_server], @default_options)
- unless @pool.servers.any? { |s| s.alive? }
- raise "#{self} unable to find server during initialization."
- end
- @mutex = Mutex.new
-
- super
+ @pool = options[:cache] || MemCache.new(@default_options[:memcache_server], @default_options)
+ unless @pool.servers.any? { |s| s.alive? }
+ raise "#{self} unable to find server during initialization."
end
+ @mutex = Mutex.new
- private
- def get_session(env, sid)
- sid ||= generate_sid
- begin
- session = @pool.get(sid) || {}
- rescue MemCache::MemCacheError, Errno::ECONNREFUSED
- session = {}
- end
- [sid, session]
- end
+ super
+ end
- def set_session(env, sid, session_data)
- options = env['rack.session.options']
- expiry = options[:expire_after] || 0
- @pool.set(sid, session_data, expiry)
- return true
+ private
+ def get_session(env, sid)
+ sid ||= generate_sid
+ begin
+ session = @pool.get(sid) || {}
rescue MemCache::MemCacheError, Errno::ECONNREFUSED
- return false
+ session = {}
end
- end
+ [sid, session]
+ end
+
+ def set_session(env, sid, session_data)
+ options = env['rack.session.options']
+ expiry = options[:expire_after] || 0
+ @pool.set(sid, session_data, expiry)
+ return true
+ rescue MemCache::MemCacheError, Errno::ECONNREFUSED
+ return false
+ end
end
end
-rescue LoadError
- # MemCache wasn't available so neither can the store be
end
View
1 actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -1,3 +1,4 @@
+require 'thread'
require 'cgi'
require 'action_view/helpers/url_helper'
require 'action_view/helpers/tag_helper'
View
26 actionpack/lib/action_view/helpers/form_helper.rb
@@ -449,6 +449,15 @@ def apply_form_for_options!(object_or_array, options) #:nodoc:
# <% end %>
# <% end %>
#
+ # Or a collection to be used:
+ #
+ # <% form_for @person, :url => { :action => "update" } do |person_form| %>
+ # ...
+ # <% person_form.fields_for :projects, @active_projects do |project_fields| %>
+ # Name: <%= project_fields.text_field :name %>
+ # <% end %>
+ # <% end %>
+ #
# When projects is already an association on Person you can use
# +accepts_nested_attributes_for+ to define the writer method for you:
#
@@ -1037,18 +1046,21 @@ def nested_attributes_association?(association_name)
def fields_for_with_nested_attributes(association_name, args, block)
name = "#{object_name}[#{association_name}_attributes]"
- association = @object.send(association_name)
- explicit_object = args.first.to_model if args.first.respond_to?(:to_model)
+ association = args.first.to_model if args.first.respond_to?(:to_model)
+
+ if association.respond_to?(:new_record?)
+ association = [association] if @object.send(association_name).is_a?(Array)
+ elsif !association.is_a?(Array)
+ association = @object.send(association_name)
+ end
if association.is_a?(Array)
- children = explicit_object ? [explicit_object] : association
explicit_child_index = args.last[:child_index] if args.last.is_a?(Hash)
-
- children.map do |child|
+ association.map do |child|
fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index(name)}]", child, args, block)
end.join
- else
- fields_for_nested_model(name, explicit_object || association, args, block)
+ elsif association
+ fields_for_nested_model(name, association, args, block)
end
end
View
1 actionpack/lib/action_view/helpers/url_helper.rb
@@ -1,4 +1,5 @@
require 'action_view/helpers/javascript_helper'
+require 'active_support/core_ext/array/access'
require 'active_support/core_ext/hash/keys'
module ActionView
View
2 actionpack/lib/action_view/template/handlers/builder.rb
@@ -6,7 +6,7 @@ class Builder < TemplateHandler
self.default_format = Mime::XML
def compile(template)
- require 'builder'
+ require 'active_support/vendor/builder'
"xml = ::Builder::XmlMarkup.new(:indent => 2);" +
"self.output_buffer = xml.target!;" +
template.source +
View
1 actionpack/lib/actionpack.rb
@@ -1 +0,0 @@
-require 'action_pack'
View
2 actionpack/test/abstract_controller/abstract_controller_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+require 'abstract_unit2'
module AbstractController
module Testing
View
4 actionpack/test/abstract_controller/callbacks_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+require 'abstract_unit2'
module AbstractController
module Testing
@@ -235,4 +235,4 @@ class TestHalting < ActiveSupport::TestCase
end
end
-end
+end
View
2 actionpack/test/abstract_controller/helper_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+require 'abstract_unit2'
module AbstractController
module Testing
View
2 actionpack/test/abstract_controller/layouts_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+require 'abstract_unit2'
require 'active_support/core_ext/class/removal'
module AbstractControllerTests
View
21 actionpack/test/abstract_controller/test_helper.rb
@@ -1,21 +0,0 @@
-$:.unshift(File.dirname(__FILE__) + '/../../lib')
-$:.unshift(File.dirname(__FILE__) + '/../../../activesupport/lib')
-$:.unshift(File.dirname(__FILE__) + '/../lib')
-
-require 'rubygems'
-require 'test/unit'
-require 'active_support'
-require 'active_support/test_case'
-require 'abstract_controller'
-require 'action_view'
-require 'action_view/base'
-require 'action_dispatch'
-require 'fixture_template'
-
-begin
- require 'ruby-debug'
- Debugger.settings[:autoeval] = true
- Debugger.start
-rescue LoadError
- # Debugging disabled. `gem install ruby-debug` to enable.
-end
View
9 actionpack/test/abstract_unit.rb
@@ -1,20 +1,19 @@
$:.unshift(File.dirname(__FILE__) + '/../lib')
$:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib')
$:.unshift(File.dirname(__FILE__) + '/../../activemodel/lib')
-$:.unshift(File.dirname(__FILE__) + '/lib')
+$:.unshift(File.dirname(__FILE__) + '/lib')
$:.unshift(File.dirname(__FILE__) + '/fixtures/helpers')
$:.unshift(File.dirname(__FILE__) + '/fixtures/alternate_helpers')
+require 'bundler_helper'
+ensure_requirable %w( rack rack/test sqlite3 )
+
ENV['TMPDIR'] = File.join(File.dirname(__FILE__), 'tmp')
ENV['new_base'] = "true"
$stderr.puts "Running old tests on new_base"
-require 'rubygems'
-gem "rack", "~> 1.0.0"
-gem "rack-test", "~> 0.4.2"
-
require 'test/unit'
require 'active_support'
require 'active_support/test_case'
View
15 actionpack/test/new_base/test_helper.rb → actionpack/test/abstract_unit2.rb
@@ -1,15 +1,20 @@
-$:.unshift(File.dirname(__FILE__) + '/../../lib')
-$:.unshift(File.dirname(__FILE__) + '/../../../activesupport/lib')
+# TODO: Unify with abstract_unit
+
+$:.unshift(File.dirname(__FILE__) + '/../lib')
+$:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib')
$:.unshift(File.dirname(__FILE__) + '/../lib')
+$:.unshift(File.dirname(__FILE__) + '/lib')
-require 'rubygems'
-gem "rack", "~> 1.0.0"
-gem "rack-test", "~> 0.4.2"
+require 'bundler_helper'
+ensure_requirable %w( rack rack/test )
require 'test/unit'
require 'active_support'
require 'active_support/test_case'
+require 'abstract_controller'
require 'action_view'
+require 'action_view/base'
+require 'action_dispatch'
require 'fixture_template'
begin
View
6 actionpack/test/lib/active_record_unit.rb → actionpack/test/active_record_unit.rb
@@ -16,7 +16,7 @@ class ActiveRecordTestConnector
else
$stderr.print 'Attempting to load Active Record... '
begin
- PATH_TO_AR = "#{File.dirname(__FILE__)}/../../../activerecord/lib"
+ PATH_TO_AR = "#{File.dirname(__FILE__)}/../../activerecord/lib"
raise LoadError, "#{PATH_TO_AR} doesn't exist" unless File.directory?(PATH_TO_AR)
$LOAD_PATH.unshift PATH_TO_AR
require 'active_record'
@@ -72,13 +72,13 @@ def setup_connection
# Load actionpack sqlite tables
def load_schema
- File.read(File.dirname(__FILE__) + "/../fixtures/db_definitions/sqlite.sql").split(';').each do |sql|
+ File.read(File.dirname(__FILE__) + "/fixtures/db_definitions/sqlite.sql").split(';').each do |sql|
ActiveRecord::Base.connection.execute(sql) unless sql.blank?
end
end
def require_fixture_models
- Dir.glob(File.dirname(__FILE__) + "/../fixtures/*.rb").each {|f| require f}
+ Dir.glob(File.dirname(__FILE__) + "/fixtures/*.rb").each {|f| require f}
end
end
end
View
10 actionpack/test/bundler_helper.rb
@@ -0,0 +1,10 @@
+def ensure_requirable(libs)
+ bundler = File.join(File.dirname(__FILE__), '..', 'vendor', 'gems', 'environment')
+ require bundler if File.exist?("#{bundler}.rb")
+
+ begin
+ libs.each { |lib| require lib }
+ rescue LoadError => e
+ abort e.message
+ end
+end
View
1 actionpack/test/controller/filter_params_test.rb
@@ -35,6 +35,7 @@ def test_filter_parameters
test_hashes = [[{},{},[]],
[{'foo'=>nil},{'foo'=>nil},[]],
[{'foo'=>'bar'},{'foo'=>'bar'},[]],
+ [{'foo'=>1},{'foo'=>1},[]],
[{'foo'=>'bar'},{'foo'=>'bar'},%w'food'],
[{'foo'=>'bar'},{'foo'=>'[FILTERED]'},%w'foo'],
[{'foo'=>'bar', 'bar'=>'foo'},{'foo'=>'[FILTERED]', 'bar'=>'foo'},%w'foo baz'],
View
1 actionpack/test/controller/rescue_test.rb
@@ -359,6 +359,7 @@ def with_test_routing
map.connect 'invalid', :controller => "rescue_test/test", :action => 'invalid'
map.connect 'b00m', :controller => "rescue_test/test", :action => 'b00m'
end
+ reset!
yield
end
end
View
5 actionpack/test/controller/resources_test.rb
@@ -135,7 +135,7 @@ def test_multiple_default_restful_routes
def test_with_custom_conditions
with_restful_routing :messages, :conditions => { :subdomain => 'app' } do
- assert_equal 'app', ActionController::Routing::Routes.named_routes.routes[:messages].conditions[:subdomain]
+ assert ActionController::Routing::Routes.recognize_path("/messages", :method => :get, :subdomain => 'app')
end
end
@@ -1130,7 +1130,8 @@ def test_default_singleton_restful_route_uses_get
map.resource :product
end
- assert_equal :get, set.named_routes.routes[:product].conditions[:method]
+ assert_routing '/product', :controller => 'products', :action => 'show'
+ assert set.recognize_path("/product", :method => :get)
end
end
View
1 actionpack/test/lib/controller/fake_controllers.rb
@@ -17,6 +17,7 @@ class CController < ActionController::Base; end
class HiController < ActionController::Base; end
class BraveController < ActionController::Base; end
class ImageController < ActionController::Base; end
+class WeblogController < ActionController::Base; end
# For speed test
class SpeedController < ActionController::Base; end
View
4 actionpack/test/new_base/base_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+require 'abstract_unit2'
# Tests the controller dispatching happy path
module Dispatching
@@ -65,4 +65,4 @@ class BaseTest < SimpleRouteCase
assert_equal 'contained_empty', Submodule::ContainedEmptyController.controller_name
end
end
-end
+end
View
4 actionpack/test/new_base/content_negotiation_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+require 'abstract_unit2'
module ContentNegotiation
@@ -15,4 +15,4 @@ class TestContentNegotiation < SimpleRouteCase
assert_body "Hello world */*!"
end
end
-end
+end
View
2 actionpack/test/new_base/content_type_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+require 'abstract_unit2'
module ContentType
class BaseController < ActionController::Base
View
4 actionpack/test/new_base/etag_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+require 'abstract_unit2'
module Etags
class BasicController < ActionController::Base
@@ -43,4 +43,4 @@ def etag_for(text)
%("#{Digest::MD5.hexdigest(text)}")
end
end
-end
+end
View
3 actionpack/test/new_base/metal_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+require 'abstract_unit2'
module MetalTest
class MetalMiddleware < ActionController::Middleware
@@ -41,4 +41,3 @@ def setup
end
end
end
-
View
77 actionpack/test/new_base/middleware_test.rb
@@ -0,0 +1,77 @@
+require 'abstract_unit2'
+
+module MiddlewareTest
+ class MyMiddleware
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ result = @app.call(env)
+ result[1]["Middleware-Test"] = "Success"
+ result[1]["Middleware-Order"] = "First"
+ result
+ end
+ end
+
+ class ExclaimerMiddleware
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ result = @app.call(env)
+ result[1]["Middleware-Order"] << "!"
+ result
+ end
+ end
+
+ class MyController < ActionController::Metal
+ use MyMiddleware
+
+ middleware.insert_before MyMiddleware, ExclaimerMiddleware
+
+ def index
+ self.response_body = "Hello World"
+ end
+ end
+
+ class InheritedController < MyController
+ end
+
+ module MiddlewareTests
+ extend ActiveSupport::Testing::Declarative
+
+ test "middleware that is 'use'd is called as part of the Rack application" do
+ result = @app.call(env_for("/"))
+ assert_equal "Hello World", result[2]
+ assert_equal "Success", result[1]["Middleware-Test"]
+ end
+
+ test "the middleware stack is exposed as 'middleware' in the controller" do
+ result = @app.call(env_for("/"))
+ assert_equal "First!", result[1]["Middleware-Order"]
+ end
+ end
+
+ class TestMiddleware < ActiveSupport::TestCase
+ include MiddlewareTests
+
+ def setup
+ @app = MyController.action(:index)
+ end
+
+ def env_for(url)
+ Rack::MockRequest.env_for(url)
+ end
+ end
+
+ class TestInheritedMiddleware < TestMiddleware
+ def setup
+ @app = InheritedController.action(:index)
+ end
+
+ test "middleware inherits" do
+ end
+ end
+end
View
1 actionpack/test/new_base/redirect_test.rb
@@ -1 +0,0 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
View
4 actionpack/test/new_base/render_action_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+require 'abstract_unit2'
module RenderAction
# This has no layout and it works
@@ -317,4 +317,4 @@ class ControllerLayoutTest < SimpleRouteCase
assert_status 200
end
end
-end
+end
View
4 actionpack/test/new_base/render_file_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+require 'abstract_unit2'
module RenderFile
@@ -107,4 +107,4 @@ def teardown
end
end
-end
+end
View
4 actionpack/test/new_base/render_implicit_action_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+require 'abstract_unit2'
module RenderImplicitAction
class SimpleController < ::ApplicationController
@@ -25,4 +25,4 @@ class RenderImplicitActionTest < SimpleRouteCase
assert_status 200
end
end
-end
+end
View
4 actionpack/test/new_base/render_layout_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+require 'abstract_unit2'
module ControllerLayouts
class ImplicitController < ::ApplicationController
@@ -98,4 +98,4 @@ class MismatchFormatTest < SimpleRouteCase
end
end
end
-end
+end
View
4 actionpack/test/new_base/render_partial_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+require 'abstract_unit2'
module RenderPartial
@@ -24,4 +24,4 @@ class TestPartial < SimpleRouteCase
end
end
-end
+end
View
4 actionpack/test/new_base/render_rjs_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+require 'abstract_unit2'
module RenderRjs
@@ -42,4 +42,4 @@ class TestBasic < SimpleRouteCase
end
end
-end
+end
View
4 actionpack/test/new_base/render_template_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+require 'abstract_unit2'
module RenderTemplate
class WithoutLayoutController < ActionController::Base
@@ -167,4 +167,4 @@ class TestTemplateRenderWithForwardSlash < SimpleRouteCase
end
end
end
-end
+end
View
4 actionpack/test/new_base/render_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+require 'abstract_unit2'
module Render
class BlankRenderController < ActionController::Base
@@ -82,4 +82,4 @@ class TestVariousObjectsAvailableInView < SimpleRouteCase
assert_body "Controller Name: blank_render"
end
end
-end
+end
View
4 actionpack/test/new_base/render_text_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+require 'abstract_unit2'
module RenderText
class SimpleController < ActionController::Base
@@ -134,4 +134,4 @@ class RenderTextTest < SimpleRouteCase
assert_status 200
end
end
-end
+end
View
4 actionpack/test/new_base/render_xml_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+require 'abstract_unit2'
module RenderXml
@@ -8,4 +8,4 @@ class BasicController < ActionController::Base
"render_xml/basic/with_render_erb" => "Hello world!"
)]
end
-end
+end
View
46 actionpack/test/old_base/abstract_unit.rb
@@ -1,46 +0,0 @@
-if ENV['new_base']
- puts *caller
- raise 'new_base/abstract_unit already loaded'
-end
-$:.unshift(File.dirname(__FILE__) + '/../lib')
-$:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib')
-$:.unshift(File.dirname(__FILE__) + '/fixtures/helpers')
-$:.unshift(File.dirname(__FILE__) + '/fixtures/alternate_helpers')
-
-require 'rubygems'
-gem "rack", "~> 1.0.0"
-gem "rack-test", "~> 0.4.2"
-
-require 'yaml'
-require 'stringio'
-require 'test/unit'
-
-begin
- require 'ruby-debug'
- Debugger.settings[:autoeval] = true
- Debugger.start
-rescue LoadError
- # Debugging disabled. `gem install ruby-debug` to enable.
-end
-
-require 'action_controller'
-require 'action_controller/testing/process'
-require 'action_view/test_case'
-
-$tags[:old_base] = true
-
-# Show backtraces for deprecated behavior for quicker cleanup.
-ActiveSupport::Deprecation.debug = true
-
-ActionController::Base.logger = nil
-ActionController::Routing::Routes.reload rescue nil
-
-ActionController::Base.session_store = nil
-
-# Register danish language for testing
-I18n.backend.store_translations 'da', {}
-I18n.backend.store_translations 'pt-BR', {}
-ORIGINAL_LOCALES = I18n.available_locales.map {|locale| locale.to_s }.sort
-
-FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures')
-ActionController::Base.view_paths = FIXTURE_LOAD_PATH
View
8 actionpack/test/runner
@@ -1,8 +0,0 @@
-#!/usr/bin/env ruby
-
-
-ARGV.each do |arg|
- Dir["#{Dir.pwd}/#{arg}/**/*_test.rb"].each do |file|
- require file
- end
-end
View
36 actionpack/test/template/form_helper_test.rb
@@ -784,6 +784,42 @@ def test_nested_fields_for_with_existing_and_new_records_on_a_nested_attributes_
assert_dom_equal expected, output_buffer
end
+ def test_nested_fields_for_with_an_empty_supplied_attributes_collection
+ form_for(:post, @post) do |f|
+ concat f.text_field(:title)
+ f.fields_for(:comments, []) do |cf|
+ concat cf.text_field(:name)
+ end
+ end
+
+ expected = '<form action="http://www.example.com" method="post">' +
+ '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
+ '</form>'
+
+ assert_dom_equal expected, output_buffer
+ end
+
+ def test_nested_fields_for_with_existing_records_on_a_supplied_nested_attributes_collection
+ @post.comments = Array.new(2) { |id| Comment.new(id + 1) }
+
+ form_for(:post, @post) do |f|
+ concat f.text_field(:title)
+ f.fields_for(:comments, @post.comments) do |cf|
+ concat cf.text_field(:name)
+ end
+ end
+
+ expected = '<form action="http://www.example.com" method="post">' +
+ '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
+ '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
+ '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
+ '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
+ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
+ '</form>'
+
+ assert_dom_equal expected, output_buffer
+ end
+
def test_nested_fields_for_on_a_nested_attributes_collection_association_yields_only_builder
@post.comments = [Comment.new(321), Comment.new]
yielded_comments = []
View
2 actionpack/test/template/form_options_helper_test.rb
@@ -1,5 +1,5 @@
require 'abstract_unit'
-require 'tzinfo'
+require 'active_support/vendor/tzinfo'
TZInfo::Timezone.cattr_reader :loaded_zones
View
1 actionpack/test/template/url_helper_test.rb
@@ -1,5 +1,6 @@
# encoding: utf-8
require 'abstract_unit'
+require 'controller/fake_controllers'
RequestMock = Struct.new("Request", :request_uri, :protocol, :host_with_port, :env)
View
3 activemodel/lib/active_model/errors.rb
@@ -1,7 +1,8 @@
require 'active_support/core_ext/string/inflections'
+require 'active_support/ordered_hash'
module ActiveModel
- class Errors < Hash
+ class Errors < ActiveSupport::OrderedHash
include DeprecatedErrorMethods
def initialize(base)
View
1 activemodel/lib/activemodel.rb
@@ -1 +0,0 @@
-require 'active_model'
View
16 activemodel/test/cases/validations_test.rb
@@ -141,6 +141,22 @@ def test_validation_order
t = Topic.new("title" => "")
assert !t.valid?
assert_equal "can't be blank", t.errors["title"].first
+ Topic.validates_presence_of :title, :author_name
+ Topic.validate {|topic| topic.errors.add('author_email_address', 'will never be valid')}
+ Topic.validates_length_of :title, :content, :minimum => 2
+
+ t = Topic.new :title => ''
+ assert !t.valid?
+
+ assert_equal :title, key = t.errors.keys.first
+ assert_equal "can't be blank", t.errors[key].first
+ assert_equal 'is too short (minimum is 2 characters)', t.errors[key].second
+ assert_equal :author_name, key = t.errors.keys.second
+ assert_equal "can't be blank", t.errors[key].first
+ assert_equal :author_email_address, key = t.errors.keys.third
+ assert_equal 'will never be valid', t.errors[key].first
+ assert_equal :content, key = t.errors.keys.fourth
+ assert_equal 'is too short (minimum is 2 characters)', t.errors[key].first
end
def test_invalid_should_be_the_opposite_of_valid
View
7 activerecord/lib/active_record/associations.rb
@@ -280,9 +280,10 @@ def association_instance_set(name, association)
# You can manipulate objects and associations before they are saved to the database, but there is some special behavior you should be
# aware of, mostly involving the saving of associated objects.
#
- # Unless you enable the :autosave option on a <tt>has_one</tt>, <tt>belongs_to</tt>,
- # <tt>has_many</tt>, or <tt>has_and_belongs_to_many</tt> association,
- # in which case the members are always saved.
+ # Unless you set the :autosave option on a <tt>has_one</tt>, <tt>belongs_to</tt>,
+ # <tt>has_many</tt>, or <tt>has_and_belongs_to_many</tt> association. Setting it
+ # to +true+ will _always_ save the members, whereas setting it to +false+ will
+ # _never_ save the members.
#
# === One-to-one associations
#
View
4 activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
@@ -24,8 +24,8 @@ def reset_column_information
def has_primary_key?
return @has_primary_key unless @has_primary_key.nil?
- @has_primary_key = (ActiveRecord::Base.connection.supports_primary_key? &&
- ActiveRecord::Base.connection.primary_key(@reflection.options[:join_table]))
+ @has_primary_key = (@owner.connection.supports_primary_key? &&
+ @owner.connection.primary_key(@reflection.options[:join_table]))
end
protected
View
52 activerecord/lib/active_record/autosave_association.rb
@@ -158,7 +158,7 @@ def #{type}(name, options = {})
def add_autosave_association_callbacks(reflection)
save_method = "autosave_associated_records_for_#{reflection.name}"
validation_method = "validate_associated_records_for_#{reflection.name}"
- validate validation_method
+ force_validation = (reflection.options[:validate] == true || reflection.options[:autosave] == true)
case reflection.macro
when :has_many, :has_and_belongs_to_many
@@ -169,7 +169,10 @@ def add_autosave_association_callbacks(reflection)
after_create save_method
after_update save_method
- define_method(validation_method) { validate_collection_association(reflection) }
+ if force_validation || (reflection.macro == :has_many && reflection.options[:validate] != false)
+ define_method(validation_method) { validate_collection_association(reflection) }
+ validate validation_method
+ end
else
case reflection.macro
when :has_one
@@ -179,7 +182,11 @@ def add_autosave_association_callbacks(reflection)
define_method(save_method) { save_belongs_to_association(reflection) }
before_save save_method
end
- define_method(validation_method) { validate_single_association(reflection) }
+
+ if force_validation
+ define_method(validation_method) { validate_single_association(reflection) }
+ validate validation_method
+ end
end
end
end
@@ -223,18 +230,16 @@ def associated_records_to_validate_or_save(association, new_record, autosave)
# Validate the association if <tt>:validate</tt> or <tt>:autosave</tt> is
# turned on for the association specified by +reflection+.
def validate_single_association(reflection)
- if reflection.options[:validate] == true || reflection.options[:autosave] == true
- if (association = association_instance_get(reflection.name)) && !association.target.nil?
- association_valid?(reflection, association)
- end
+ if (association = association_instance_get(reflection.name)) && !association.target.nil?
+ association_valid?(reflection, association)
end
end
# Validate the associated records if <tt>:validate</tt> or
# <tt>:autosave</tt> is turned on for the association specified by
# +reflection+.
def validate_collection_association(reflection)
- if reflection.options[:validate] != false && association = association_instance_get(reflection.name)
+ if association = association_instance_get(reflection.name)
if records = associated_records_to_validate_or_save(association, new_record?, reflection.options[:autosave])
records.each { |record| association_valid?(reflection, record) }
end
@@ -243,15 +248,15 @@ def validate_collection_association(reflection)
# Returns whether or not the association is valid and applies any errors to
# the parent, <tt>self</tt>, if it wasn't. Skips any <tt>:autosave</tt>
- # enabled records if they're marked_for_destruction?.
+ # enabled records if they're marked_for_destruction? or destroyed.
def association_valid?(reflection, association)
+ return true if association.destroyed? || association.marked_for_destruction?
+
unless valid = association.valid?
if reflection.options[:autosave]
- unless association.marked_for_destruction?
- association.errors.each do |attribute, message|
- attribute = "#{reflection.name}_#{attribute}"
- errors[attribute] << message if errors[attribute].empty?
- end
+ association.errors.each do |attribute, message|
+ attribute = "#{reflection.name}_#{attribute}"
+ errors[attribute] << message if errors[attribute].empty?
end
else
errors.add(reflection.name)
@@ -281,9 +286,11 @@ def save_collection_association(reflection)
if records = associated_records_to_validate_or_save(association, @new_record_before_save, autosave)
records.each do |record|
+ next if record.destroyed?
+
if autosave && record.marked_for_destruction?
association.destroy(record)
- elsif @new_record_before_save || record.new_record?
+ elsif autosave != false && (@new_record_before_save || record.new_record?)
if autosave
association.send(:insert_record, record, false, false)
else
@@ -309,14 +316,17 @@ def save_collection_association(reflection)
# This all happens inside a transaction, _if_ the Transactions module is included into
# ActiveRecord::Base after the AutosaveAssociation module, which it does by default.
def save_has_one_association(reflection)
- if (association = association_instance_get(reflection.name)) && !association.target.nil?
+ if (association = association_instance_get(reflection.name)) && !association.target.nil? && !association.destroyed?
autosave = reflection.options[:autosave]
if autosave && association.marked_for_destruction?
association.destroy
- elsif new_record? || association.new_record? || association[reflection.primary_key_name] != id || autosave
- association[reflection.primary_key_name] = id
- association.save(!autosave)
+ else
+ key = reflection.options[:primary_key] ? send(reflection.options[:primary_key]) : id
+ if autosave != false && (new_record? || association.new_record? || association[reflection.primary_key_name] != key || autosave)
+ association[reflection.primary_key_name] = key
+ association.save(!autosave)
+ end
end
end
end
@@ -330,12 +340,12 @@ def save_has_one_association(reflection)
# This all happens inside a transaction, _if_ the Transactions module is included into
# ActiveRecord::Base after the AutosaveAssociation module, which it does by default.
def save_belongs_to_association(reflection)
- if association = association_instance_get(reflection.name)
+ if (association = association_instance_get(reflection.name)) && !association.destroyed?
autosave = reflection.options[:autosave]
if autosave && association.marked_for_destruction?
association.destroy
- else
+ elsif autosave != false
association.save(!autosave) if association.new_record? || autosave
if association.updated?
View
3 activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -8,7 +8,8 @@ def self.define_all_hashes_method!
raise 'Mysql not loaded' unless defined?(::Mysql)
target = defined?(Mysql::Result) ? Mysql::Result : MysqlRes
- return if target.instance_methods.include?('all_hashes')
+ return if target.instance_methods.include?('all_hashes') ||
+ target.instance_methods.include?(:all_hashes)
# Ruby driver has a version string and returns null values in each_hash
# C driver >= 2.7 returns null values in each_hash
View
22 activerecord/lib/active_record/locking/pessimistic.rb
@@ -1,25 +1,3 @@
-# Copyright (c) 2006 Shugo Maeda <shugo@ruby-lang.org>
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject
-# to the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
-# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
-# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
module ActiveRecord
module Locking
# Locking::Pessimistic provides support for row-level locking using
View
60 activerecord/lib/active_record/nested_attributes.rb
@@ -66,10 +66,10 @@ module NestedAttributes #:nodoc:
# accepts_nested_attributes_for :avatar, :allow_destroy => true
# end
#
- # Now, when you add the <tt>_delete</tt> key to the attributes hash, with a
+ # Now, when you add the <tt>_destroy</tt> key to the attributes hash, with a
# value that evaluates to +true+, you will destroy the associated model:
#
- # member.avatar_attributes = { :id => '2', :_delete => '1' }
+ # member.avatar_attributes = { :id => '2', :_destroy => '1' }
# member.avatar.marked_for_destruction? # => true
# member.save
# member.avatar #=> nil
@@ -89,14 +89,14 @@ module NestedAttributes #:nodoc:
# the attribute hash.
#
# For each hash that does _not_ have an <tt>id</tt> key a new record will
- # be instantiated, unless the hash also contains a <tt>_delete</tt> key
+ # be instantiated, unless the hash also contains a <tt>_destroy</tt> key
# that evaluates to +true+.
#
# params = { :member => {
# :name => 'joe', :posts_attributes => [
# { :title => 'Kari, the awesome Ruby documentation browser!' },
# { :title => 'The egalitarian assumption of the modern citizen' },
- # { :title => '', :_delete => '1' } # this will be ignored
+ # { :title => '', :_destroy => '1' } # this will be ignored
# ]
# }}
#
@@ -144,7 +144,7 @@ module NestedAttributes #:nodoc:
# By default the associated records are protected from being destroyed. If
# you want to destroy any of the associated records through the attributes
# hash, you have to enable it first using the <tt>:allow_destroy</tt>
- # option. This will allow you to also use the <tt>_delete</tt> key to
+ # option. This will allow you to also use the <tt>_destroy</tt> key to
# destroy existing records:
#
# class Member < ActiveRecord::Base
@@ -153,7 +153,7 @@ module NestedAttributes #:nodoc:
# end
#
# params = { :member => {
- # :posts_attributes => [{ :id => '2', :_delete => '1' }]
+ # :posts_attributes => [{ :id => '2', :_destroy => '1' }]
# }}
#
# member.attributes = params['member']
@@ -176,14 +176,14 @@ module ClassMethods
# Supported options:
# [:allow_destroy]
# If true, destroys any members from the attributes hash with a
- # <tt>_delete</tt> key and a value that evaluates to +true+
+ # <tt>_destroy</tt> key and a value that evaluates to +true+
# (eg. 1, '1', true, or 'true'). This option is off by default.
# [:reject_if]
# Allows you to specify a Proc that checks whether a record should be
# built for a certain attribute hash. The hash is passed to the Proc
# and the Proc should return either +true+ or +false+. When no Proc
# is specified a record will be built for all attribute hashes that
- # do not have a <tt>_delete</tt> that evaluates to true.
+ # do not have a <tt>_destroy</tt> value that evaluates to true.
# Passing <tt>:all_blank</tt> instead of a Proc will create a proc
# that will reject a record where all the attributes are blank.
#
@@ -236,15 +236,25 @@ def #{association_name}_attributes=(attributes)
# destruction of this association.
#
# See ActionView::Helpers::FormHelper::fields_for for more info.
- def _delete
+ def _destroy
marked_for_destruction?
end
+ # Deal with deprecated _delete.
+ #
+ def _delete #:nodoc:
+ ActiveSupport::Deprecation.warn "_delete is deprecated in nested attributes. Use _destroy instead."
+ _destroy
+ end
+
private
# Attribute hash keys that should not be assigned as normal attributes.
# These hash keys are nested attributes implementation details.
- UNASSIGNABLE_KEYS = %w{ id _delete }
+ #
+ # TODO Remove _delete from UNASSIGNABLE_KEYS when deprecation warning are
+ # removed.
+ UNASSIGNABLE_KEYS = %w( id _destroy _delete )
# Assigns the given attributes to the association.
#
@@ -253,14 +263,19 @@ def _delete
# record will be built.
#
# If the given attributes include a matching <tt>:id</tt> attribute _and_ a
- # <tt>:_delete</tt> key set to a truthy value, then the existing record
+ # <tt>:_destroy</tt> key set to a truthy value, then the existing record
# will be marked for destruction.
def assign_nested_attributes_for_one_to_one_association(association_name, attributes, allow_destroy)
attributes = attributes.stringify_keys
if attributes['id'].blank?
unless reject_new_record?(association_name, attributes)
- send("build_#{association_name}", attributes.except(*UNASSIGNABLE_KEYS))
+ method = "build_#{association_name}"
+ if respond_to?(method)
+ send(method, attributes.except(*UNASSIGNABLE_KEYS))
+ else
+ raise ArgumentError, "Cannot build association #{association_name}. Are you trying to build a polymorphic one-to-one association?"
+ end
end
elsif (existing_record = send(association_name)) && existing_record.id.to_s == attributes['id'].to_s
assign_to_or_mark_for_destruction(existing_record, attributes, allow_destroy)
@@ -272,15 +287,15 @@ def assign_nested_attributes_for_one_to_one_association(association_name, attrib
# Hashes with an <tt>:id</tt> value matching an existing associated record
# will update that record. Hashes without an <tt>:id</tt> value will build
# a new record for the association. Hashes with a matching <tt>:id</tt>
- # value and a <tt>:_delete</tt> key set to a truthy value will mark the
+ # value and a <tt>:_destroy</tt> key set to a truthy value will mark the
# matched record for destruction.
#
# For example:
#
# assign_nested_attributes_for_collection_association(:people, {
# '1' => { :id => '1', :name => 'Peter' },
# '2' => { :name => 'John' },
- # '3' => { :id => '2', :_delete => true }
+ # '3' => { :id => '2', :_destroy => true }
# })
#
# Will update the name of the Person with ID 1, build a new associated
@@ -292,7 +307,7 @@ def assign_nested_attributes_for_one_to_one_association(association_name, attrib
# assign_nested_attributes_for_collection_association(:people, [
# { :id => '1', :name => 'Peter' },
# { :name => 'John' },
- # { :id => '2', :_delete => true }
+ # { :id => '2', :_destroy => true }
# ])
def assign_nested_attributes_for_collection_association(association_name, attributes_collection, allow_destroy)
unless attributes_collection.is_a?(Hash) || attributes_collection.is_a?(Array)
@@ -317,25 +332,26 @@ def assign_nested_attributes_for_collection_association(association_name, attrib
end
# Updates a record with the +attributes+ or marks it for destruction if
- # +allow_destroy+ is +true+ and has_delete_flag? returns +true+.
+ # +allow_destroy+ is +true+ and has_destroy_flag? returns +true+.
def assign_to_or_mark_for_destruction(record, attributes, allow_destroy)
- if has_delete_flag?(attributes) && allow_destroy
+ if has_destroy_flag?(attributes) && allow_destroy
record.mark_for_destruction
else
record.attributes = attributes.except(*UNASSIGNABLE_KEYS)
end
end
- # Determines if a hash contains a truthy _delete key.
- def has_delete_flag?(hash)
- ConnectionAdapters::Column.value_to_boolean hash['_delete']
+ # Determines if a hash contains a truthy _destroy key.
+ def has_destroy_flag?(hash)
+ ConnectionAdapters::Column.value_to_boolean(hash['_destroy']) ||
+ ConnectionAdapters::Column.value_to_boolean(hash['_delete']) # TODO Remove after deprecation.
end
# Determines if a new record should be build by checking for
- # has_delete_flag? or if a <tt>:reject_if</tt> proc exists for this
+ # has_destroy_flag? or if a <tt>:reject_if</tt> proc exists for this
# association and evaluates to +true+.
def reject_new_record?(association_name, attributes)
- has_delete_flag?(attributes) ||
+ has_destroy_flag?(attributes) ||
self.class.reject_new_nested_attributes_procs[association_name].try(:call, attributes)
end
end
View
1 activerecord/lib/activerecord.rb
@@ -1 +0,0 @@
-require 'active_record'
View
9 activerecord/test/cases/associations/has_one_associations_test.rb
@@ -36,6 +36,15 @@ def test_finding_using_primary_key
assert_equal accounts(:rails_core_account), firm.account_using_primary_key
end
+ def test_update_with_foreign_and_primary_keys
+ firm = companies(:first_firm)
+ account = firm.account_using_foreign_and_primary_keys
+ assert_equal Account.find_by_firm_name(firm.name), account
+ firm.save
+ firm.reload
+ assert_equal account, firm.account_using_foreign_and_primary_keys
+ end
+
def test_can_marshal_has_one_association_with_nil_target
firm = Firm.new
assert_nothing_raised do
View
221 activerecord/test/cases/autosave_association_test.rb
@@ -443,6 +443,70 @@ def test_replace_on_new_object
end
end
+class TestDefaultAutosaveAssociationOnNewRecord < ActiveRecord::TestCase
+ def test_autosave_new_record_on_belongs_to_can_be_disabled_per_relationship
+ new_account = Account.new("credit_limit" => 1000)
+ new_firm = Firm.new("name" => "some firm")
+
+ assert new_firm.new_record?
+ new_account.firm = new_firm
+ new_account.save!
+
+ assert !new_firm.new_record?
+
+ new_account = Account.new("credit_limit" => 1000)
+ new_autosaved_firm = Firm.new("name" => "some firm")
+
+ assert new_autosaved_firm.new_record?
+ new_account.unautosaved_firm = new_autosaved_firm
+ new_account.save!
+
+ assert new_autosaved_firm.new_record?
+ end
+
+ def test_autosave_new_record_on_has_one_can_be_disabled_per_relationship
+ firm = Firm.new("name" => "some firm")
+ account = Account.new("credit_limit" => 1000)
+
+ assert account.new_record?
+ firm.account = account
+ firm.save!
+
+ assert !account.new_record?
+
+ firm = Firm.new("name" => "some firm")
+ account = Account.new("credit_limit" => 1000)
+
+ firm.unautosaved_account = account
+
+ assert account.new_record?
+ firm.unautosaved_account = account
+ firm.save!
+
+ assert account.new_record?
+ end
+
+ def test_autosave_new_record_on_has_many_can_be_disabled_per_relationship
+ firm = Firm.new("name" => "some firm")