ibm_db 3.0.5 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (580) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +4 -0
  3. data/LICENSE +1 -1
  4. data/MANIFEST +14 -14
  5. data/ParameterizedQueries README +6 -6
  6. data/README +208 -225
  7. data/ext/Makefile.nt32 +181 -181
  8. data/ext/Makefile.nt32.191 +212 -212
  9. data/ext/extconf.rb +291 -291
  10. data/ext/ibm_db.c +11887 -11887
  11. data/ext/ruby_ibm_db.h +241 -241
  12. data/ext/ruby_ibm_db_cli.c +866 -866
  13. data/ext/ruby_ibm_db_cli.h +500 -500
  14. data/init.rb +41 -41
  15. data/lib/IBM_DB.rb +27 -27
  16. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +3452 -3177
  17. data/lib/active_record/connection_adapters/ibmdb_adapter.rb +5 -2
  18. data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -328
  19. data/test/active_record/connection_adapters/fake_adapter.rb +49 -46
  20. data/test/assets/example.log +1 -1
  21. data/test/assets/test.txt +1 -1
  22. data/test/cases/adapter_test.rb +351 -276
  23. data/test/cases/adapters/mysql2/active_schema_test.rb +193 -0
  24. data/test/cases/adapters/mysql2/bind_parameter_test.rb +50 -0
  25. data/test/cases/adapters/mysql2/boolean_test.rb +100 -0
  26. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +63 -0
  27. data/test/cases/adapters/mysql2/charset_collation_test.rb +54 -0
  28. data/test/cases/adapters/mysql2/connection_test.rb +210 -0
  29. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +45 -0
  30. data/test/cases/adapters/mysql2/enum_test.rb +26 -0
  31. data/test/cases/adapters/mysql2/explain_test.rb +21 -0
  32. data/test/cases/adapters/mysql2/json_test.rb +195 -0
  33. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +83 -0
  34. data/test/cases/adapters/mysql2/reserved_word_test.rb +152 -0
  35. data/test/cases/adapters/mysql2/schema_migrations_test.rb +59 -0
  36. data/test/cases/adapters/mysql2/schema_test.rb +126 -0
  37. data/test/cases/adapters/mysql2/sp_test.rb +36 -0
  38. data/test/cases/adapters/mysql2/sql_types_test.rb +14 -0
  39. data/test/cases/adapters/mysql2/table_options_test.rb +42 -0
  40. data/test/cases/adapters/mysql2/unsigned_type_test.rb +66 -0
  41. data/test/cases/adapters/postgresql/active_schema_test.rb +98 -0
  42. data/test/cases/adapters/postgresql/array_test.rb +339 -0
  43. data/test/cases/adapters/postgresql/bit_string_test.rb +82 -0
  44. data/test/cases/adapters/postgresql/bytea_test.rb +134 -0
  45. data/test/cases/adapters/postgresql/case_insensitive_test.rb +26 -0
  46. data/test/cases/adapters/postgresql/change_schema_test.rb +38 -0
  47. data/test/cases/adapters/postgresql/cidr_test.rb +25 -0
  48. data/test/cases/adapters/postgresql/citext_test.rb +78 -0
  49. data/test/cases/adapters/postgresql/collation_test.rb +53 -0
  50. data/test/cases/adapters/postgresql/composite_test.rb +132 -0
  51. data/test/cases/adapters/postgresql/connection_test.rb +257 -0
  52. data/test/cases/adapters/postgresql/datatype_test.rb +92 -0
  53. data/test/cases/adapters/postgresql/domain_test.rb +47 -0
  54. data/test/cases/adapters/postgresql/enum_test.rb +91 -0
  55. data/test/cases/adapters/postgresql/explain_test.rb +20 -0
  56. data/test/cases/adapters/postgresql/extension_migration_test.rb +63 -0
  57. data/test/cases/adapters/postgresql/full_text_test.rb +44 -0
  58. data/test/cases/adapters/postgresql/geometric_test.rb +378 -0
  59. data/test/cases/adapters/postgresql/hstore_test.rb +382 -0
  60. data/test/cases/adapters/postgresql/infinity_test.rb +69 -0
  61. data/test/cases/adapters/postgresql/integer_test.rb +25 -0
  62. data/test/cases/adapters/postgresql/json_test.rb +237 -0
  63. data/test/cases/adapters/postgresql/ltree_test.rb +53 -0
  64. data/test/cases/adapters/postgresql/money_test.rb +96 -0
  65. data/test/cases/adapters/postgresql/network_test.rb +94 -0
  66. data/test/cases/adapters/postgresql/numbers_test.rb +49 -0
  67. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +405 -0
  68. data/test/cases/adapters/postgresql/prepared_statements_test.rb +22 -0
  69. data/test/cases/adapters/postgresql/quoting_test.rb +44 -0
  70. data/test/cases/adapters/postgresql/range_test.rb +343 -0
  71. data/test/cases/adapters/postgresql/referential_integrity_test.rb +111 -0
  72. data/test/cases/adapters/postgresql/rename_table_test.rb +34 -0
  73. data/test/cases/adapters/postgresql/schema_authorization_test.rb +119 -0
  74. data/test/cases/adapters/postgresql/schema_test.rb +597 -0
  75. data/test/cases/adapters/postgresql/serial_test.rb +154 -0
  76. data/test/cases/adapters/postgresql/statement_pool_test.rb +41 -0
  77. data/test/cases/adapters/postgresql/timestamp_test.rb +90 -0
  78. data/test/cases/adapters/postgresql/type_lookup_test.rb +33 -0
  79. data/test/cases/adapters/postgresql/utils_test.rb +62 -0
  80. data/test/cases/adapters/postgresql/uuid_test.rb +294 -0
  81. data/test/cases/adapters/postgresql/xml_test.rb +54 -0
  82. data/test/cases/adapters/sqlite3/collation_test.rb +53 -0
  83. data/test/cases/adapters/sqlite3/copy_table_test.rb +98 -0
  84. data/test/cases/adapters/sqlite3/explain_test.rb +21 -0
  85. data/test/cases/adapters/sqlite3/quoting_test.rb +101 -0
  86. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +441 -0
  87. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +24 -0
  88. data/test/cases/adapters/sqlite3/statement_pool_test.rb +20 -0
  89. data/test/cases/aggregations_test.rb +168 -158
  90. data/test/cases/ar_schema_test.rb +146 -161
  91. data/test/cases/associations/association_scope_test.rb +16 -21
  92. data/test/cases/associations/belongs_to_associations_test.rb +1141 -1029
  93. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +41 -0
  94. data/test/cases/associations/callbacks_test.rb +190 -192
  95. data/test/cases/associations/cascaded_eager_loading_test.rb +188 -188
  96. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +36 -36
  97. data/test/cases/associations/eager_load_nested_include_test.rb +126 -128
  98. data/test/cases/associations/eager_singularization_test.rb +148 -148
  99. data/test/cases/associations/eager_test.rb +1514 -1429
  100. data/test/cases/associations/extension_test.rb +87 -82
  101. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +1004 -972
  102. data/test/cases/associations/has_many_associations_test.rb +2501 -2182
  103. data/test/cases/associations/has_many_through_associations_test.rb +1271 -1204
  104. data/test/cases/associations/has_one_associations_test.rb +707 -610
  105. data/test/cases/associations/has_one_through_associations_test.rb +383 -380
  106. data/test/cases/associations/inner_join_association_test.rb +139 -139
  107. data/test/cases/associations/inverse_associations_test.rb +733 -706
  108. data/test/cases/associations/join_model_test.rb +777 -754
  109. data/test/cases/associations/left_outer_join_association_test.rb +88 -0
  110. data/test/cases/associations/nested_through_associations_test.rb +579 -579
  111. data/test/cases/associations/required_test.rb +102 -82
  112. data/test/cases/associations_test.rb +385 -380
  113. data/test/cases/attribute_decorators_test.rb +125 -125
  114. data/test/cases/attribute_methods/read_test.rb +60 -60
  115. data/test/cases/attribute_methods_test.rb +1009 -952
  116. data/test/cases/attribute_set_test.rb +270 -210
  117. data/test/cases/attribute_test.rb +246 -180
  118. data/test/cases/attributes_test.rb +253 -136
  119. data/test/cases/autosave_association_test.rb +1708 -1595
  120. data/test/cases/base_test.rb +1713 -1664
  121. data/test/cases/batches_test.rb +489 -212
  122. data/test/cases/binary_test.rb +44 -52
  123. data/test/cases/bind_parameter_test.rb +110 -100
  124. data/test/cases/cache_key_test.rb +25 -0
  125. data/test/cases/calculations_test.rb +798 -646
  126. data/test/cases/callbacks_test.rb +636 -543
  127. data/test/cases/clone_test.rb +40 -40
  128. data/test/cases/coders/json_test.rb +15 -0
  129. data/test/cases/coders/yaml_column_test.rb +63 -63
  130. data/test/cases/collection_cache_key_test.rb +115 -0
  131. data/test/cases/column_alias_test.rb +17 -17
  132. data/test/cases/column_definition_test.rb +92 -123
  133. data/test/cases/comment_test.rb +143 -0
  134. data/test/cases/connection_adapters/adapter_leasing_test.rb +56 -54
  135. data/test/cases/connection_adapters/connection_handler_test.rb +160 -53
  136. data/test/cases/connection_adapters/connection_specification_test.rb +12 -12
  137. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +255 -293
  138. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +69 -65
  139. data/test/cases/connection_adapters/quoting_test.rb +13 -13
  140. data/test/cases/connection_adapters/schema_cache_test.rb +61 -56
  141. data/test/cases/connection_adapters/type_lookup_test.rb +118 -110
  142. data/test/cases/connection_management_test.rb +112 -122
  143. data/test/cases/connection_pool_test.rb +521 -346
  144. data/test/cases/connection_specification/resolver_test.rb +131 -116
  145. data/test/cases/core_test.rb +112 -112
  146. data/test/cases/counter_cache_test.rb +214 -209
  147. data/test/cases/custom_locking_test.rb +17 -17
  148. data/test/cases/database_statements_test.rb +34 -19
  149. data/test/cases/{invalid_date_test.rb → date_test.rb} +44 -32
  150. data/test/cases/date_time_precision_test.rb +106 -0
  151. data/test/cases/date_time_test.rb +61 -61
  152. data/test/cases/defaults_test.rb +218 -223
  153. data/test/cases/dirty_test.rb +763 -785
  154. data/test/cases/disconnected_test.rb +30 -28
  155. data/test/cases/dup_test.rb +157 -157
  156. data/test/cases/enum_test.rb +444 -290
  157. data/test/cases/errors_test.rb +16 -0
  158. data/test/cases/explain_subscriber_test.rb +64 -64
  159. data/test/cases/explain_test.rb +87 -76
  160. data/test/cases/finder_respond_to_test.rb +60 -60
  161. data/test/cases/finder_test.rb +1294 -1169
  162. data/test/cases/fixture_set/file_test.rb +156 -138
  163. data/test/cases/fixtures_test.rb +988 -908
  164. data/test/cases/forbidden_attributes_protection_test.rb +165 -99
  165. data/test/cases/habtm_destroy_order_test.rb +61 -61
  166. data/test/cases/helper.rb +204 -210
  167. data/test/cases/hot_compatibility_test.rb +142 -54
  168. data/test/cases/i18n_test.rb +45 -45
  169. data/test/cases/inheritance_test.rb +606 -375
  170. data/test/cases/integration_test.rb +155 -139
  171. data/test/cases/invalid_connection_test.rb +24 -22
  172. data/test/cases/invertible_migration_test.rb +387 -295
  173. data/test/cases/json_serialization_test.rb +311 -302
  174. data/test/cases/locking_test.rb +493 -477
  175. data/test/cases/log_subscriber_test.rb +225 -136
  176. data/test/cases/migration/change_schema_test.rb +458 -512
  177. data/test/cases/migration/change_table_test.rb +256 -224
  178. data/test/cases/migration/column_attributes_test.rb +176 -192
  179. data/test/cases/migration/column_positioning_test.rb +56 -56
  180. data/test/cases/migration/columns_test.rb +310 -304
  181. data/test/cases/migration/command_recorder_test.rb +350 -305
  182. data/test/cases/migration/compatibility_test.rb +118 -0
  183. data/test/cases/migration/create_join_table_test.rb +157 -148
  184. data/test/cases/migration/foreign_key_test.rb +360 -328
  185. data/test/cases/migration/helper.rb +39 -39
  186. data/test/cases/migration/index_test.rb +218 -216
  187. data/test/cases/migration/logger_test.rb +36 -36
  188. data/test/cases/migration/pending_migrations_test.rb +52 -53
  189. data/test/cases/migration/references_foreign_key_test.rb +216 -169
  190. data/test/cases/migration/references_index_test.rb +101 -101
  191. data/test/cases/migration/references_statements_test.rb +136 -116
  192. data/test/cases/migration/rename_table_test.rb +93 -93
  193. data/test/cases/migration_test.rb +1157 -959
  194. data/test/cases/migrator_test.rb +470 -388
  195. data/test/cases/mixin_test.rb +68 -70
  196. data/test/cases/modules_test.rb +172 -173
  197. data/test/cases/multiparameter_attributes_test.rb +372 -350
  198. data/test/cases/multiple_db_test.rb +122 -115
  199. data/test/cases/nested_attributes_test.rb +1098 -1070
  200. data/test/cases/nested_attributes_with_callbacks_test.rb +144 -144
  201. data/test/cases/persistence_test.rb +1001 -909
  202. data/test/cases/pooled_connections_test.rb +81 -81
  203. data/test/cases/primary_keys_test.rb +376 -237
  204. data/test/cases/query_cache_test.rb +446 -326
  205. data/test/cases/quoting_test.rb +202 -156
  206. data/test/cases/readonly_test.rb +119 -118
  207. data/test/cases/reaper_test.rb +85 -85
  208. data/test/cases/reflection_test.rb +509 -463
  209. data/test/cases/relation/delegation_test.rb +63 -68
  210. data/test/cases/relation/merging_test.rb +157 -161
  211. data/test/cases/relation/mutation_test.rb +183 -165
  212. data/test/cases/relation/or_test.rb +92 -0
  213. data/test/cases/relation/predicate_builder_test.rb +16 -14
  214. data/test/cases/relation/record_fetch_warning_test.rb +40 -0
  215. data/test/cases/relation/where_chain_test.rb +105 -181
  216. data/test/cases/relation/where_clause_test.rb +182 -0
  217. data/test/cases/relation/where_test.rb +322 -300
  218. data/test/cases/relation_test.rb +328 -319
  219. data/test/cases/relations_test.rb +2026 -1815
  220. data/test/cases/reload_models_test.rb +22 -22
  221. data/test/cases/result_test.rb +90 -80
  222. data/test/cases/sanitize_test.rb +176 -83
  223. data/test/cases/schema_dumper_test.rb +457 -463
  224. data/test/cases/schema_loading_test.rb +52 -0
  225. data/test/cases/scoping/default_scoping_test.rb +528 -454
  226. data/test/cases/scoping/named_scoping_test.rb +561 -524
  227. data/test/cases/scoping/relation_scoping_test.rb +400 -357
  228. data/test/cases/secure_token_test.rb +32 -0
  229. data/test/cases/serialization_test.rb +104 -104
  230. data/test/cases/serialized_attribute_test.rb +364 -277
  231. data/test/cases/statement_cache_test.rb +136 -98
  232. data/test/cases/store_test.rb +195 -194
  233. data/test/cases/suppressor_test.rb +63 -0
  234. data/test/cases/tasks/database_tasks_test.rb +462 -398
  235. data/test/cases/tasks/mysql_rake_test.rb +345 -324
  236. data/test/cases/tasks/postgresql_rake_test.rb +304 -250
  237. data/test/cases/tasks/sqlite_rake_test.rb +220 -193
  238. data/test/cases/test_case.rb +131 -123
  239. data/test/cases/test_fixtures_test.rb +36 -0
  240. data/test/cases/time_precision_test.rb +102 -0
  241. data/test/cases/timestamp_test.rb +501 -467
  242. data/test/cases/touch_later_test.rb +121 -0
  243. data/test/cases/transaction_callbacks_test.rb +518 -452
  244. data/test/cases/transaction_isolation_test.rb +106 -106
  245. data/test/cases/transactions_test.rb +834 -817
  246. data/test/cases/type/adapter_specific_registry_test.rb +133 -0
  247. data/test/cases/type/date_time_test.rb +14 -0
  248. data/test/cases/type/integer_test.rb +27 -121
  249. data/test/cases/type/string_test.rb +22 -36
  250. data/test/cases/type/type_map_test.rb +177 -177
  251. data/test/cases/type_test.rb +39 -0
  252. data/test/cases/types_test.rb +24 -141
  253. data/test/cases/unconnected_test.rb +33 -33
  254. data/test/cases/validations/absence_validation_test.rb +73 -0
  255. data/test/cases/validations/association_validation_test.rb +97 -86
  256. data/test/cases/validations/i18n_generate_message_validation_test.rb +84 -84
  257. data/test/cases/validations/i18n_validation_test.rb +86 -90
  258. data/test/cases/validations/length_validation_test.rb +79 -47
  259. data/test/cases/validations/presence_validation_test.rb +103 -68
  260. data/test/cases/validations/uniqueness_validation_test.rb +548 -457
  261. data/test/cases/validations_repair_helper.rb +19 -23
  262. data/test/cases/validations_test.rb +194 -165
  263. data/test/cases/view_test.rb +216 -119
  264. data/test/cases/yaml_serialization_test.rb +121 -126
  265. data/test/config.example.yml +97 -0
  266. data/test/config.rb +5 -5
  267. data/test/fixtures/accounts.yml +29 -29
  268. data/test/fixtures/admin/accounts.yml +2 -2
  269. data/test/fixtures/admin/users.yml +10 -10
  270. data/test/fixtures/author_addresses.original +11 -0
  271. data/test/fixtures/author_addresses.yml +17 -17
  272. data/test/fixtures/author_favorites.yml +3 -3
  273. data/test/fixtures/authors.original +17 -0
  274. data/test/fixtures/authors.yml +23 -23
  275. data/test/fixtures/bad_posts.yml +9 -0
  276. data/test/fixtures/binaries.yml +133 -133
  277. data/test/fixtures/books.yml +31 -11
  278. data/test/fixtures/bulbs.yml +5 -5
  279. data/test/fixtures/cars.yml +9 -9
  280. data/test/fixtures/categories.yml +19 -19
  281. data/test/fixtures/categories/special_categories.yml +9 -9
  282. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -4
  283. data/test/fixtures/categories_ordered.yml +7 -7
  284. data/test/fixtures/categories_posts.yml +31 -31
  285. data/test/fixtures/categorizations.yml +23 -23
  286. data/test/fixtures/clubs.yml +8 -8
  287. data/test/fixtures/collections.yml +3 -3
  288. data/test/fixtures/colleges.yml +3 -3
  289. data/test/fixtures/comments.yml +65 -65
  290. data/test/fixtures/companies.yml +67 -67
  291. data/test/fixtures/computers.yml +10 -10
  292. data/test/fixtures/content.yml +3 -0
  293. data/test/fixtures/content_positions.yml +3 -0
  294. data/test/fixtures/courses.yml +8 -8
  295. data/test/fixtures/customers.yml +25 -25
  296. data/test/fixtures/dashboards.yml +6 -6
  297. data/test/fixtures/dead_parrots.yml +5 -0
  298. data/test/fixtures/developers.yml +22 -22
  299. data/test/fixtures/developers_projects.yml +16 -16
  300. data/test/fixtures/dog_lovers.yml +7 -7
  301. data/test/fixtures/dogs.yml +4 -4
  302. data/test/fixtures/doubloons.yml +3 -3
  303. data/test/fixtures/edges.yml +5 -5
  304. data/test/fixtures/entrants.yml +14 -14
  305. data/test/fixtures/essays.yml +6 -6
  306. data/test/fixtures/faces.yml +11 -11
  307. data/test/fixtures/fk_test_has_fk.yml +3 -3
  308. data/test/fixtures/fk_test_has_pk.yml +1 -1
  309. data/test/fixtures/friendships.yml +4 -4
  310. data/test/fixtures/funny_jokes.yml +10 -10
  311. data/test/fixtures/interests.yml +33 -33
  312. data/test/fixtures/items.yml +3 -3
  313. data/test/fixtures/jobs.yml +7 -7
  314. data/test/fixtures/legacy_things.yml +3 -3
  315. data/test/fixtures/live_parrots.yml +4 -0
  316. data/test/fixtures/mateys.yml +4 -4
  317. data/test/fixtures/member_details.yml +8 -8
  318. data/test/fixtures/member_types.yml +6 -6
  319. data/test/fixtures/members.yml +11 -11
  320. data/test/fixtures/memberships.yml +34 -34
  321. data/test/fixtures/men.yml +5 -5
  322. data/test/fixtures/minimalistics.yml +2 -2
  323. data/test/fixtures/minivans.yml +5 -5
  324. data/test/fixtures/mixed_case_monkeys.yml +6 -6
  325. data/test/fixtures/mixins.yml +29 -29
  326. data/test/fixtures/movies.yml +7 -7
  327. data/test/fixtures/naked/yml/accounts.yml +1 -1
  328. data/test/fixtures/naked/yml/companies.yml +1 -1
  329. data/test/fixtures/naked/yml/courses.yml +1 -1
  330. data/test/fixtures/naked/yml/parrots.yml +2 -0
  331. data/test/fixtures/naked/yml/trees.yml +3 -0
  332. data/test/fixtures/nodes.yml +29 -0
  333. data/test/fixtures/organizations.yml +5 -5
  334. data/test/fixtures/other_comments.yml +6 -0
  335. data/test/fixtures/other_dogs.yml +2 -0
  336. data/test/fixtures/other_posts.yml +7 -0
  337. data/test/fixtures/other_topics.yml +42 -42
  338. data/test/fixtures/owners.yml +9 -9
  339. data/test/fixtures/parrots.yml +27 -27
  340. data/test/fixtures/parrots_pirates.yml +7 -7
  341. data/test/fixtures/people.yml +24 -24
  342. data/test/fixtures/peoples_treasures.yml +3 -3
  343. data/test/fixtures/pets.yml +19 -19
  344. data/test/fixtures/pirates.yml +15 -12
  345. data/test/fixtures/posts.yml +80 -80
  346. data/test/fixtures/price_estimates.yml +16 -7
  347. data/test/fixtures/products.yml +4 -4
  348. data/test/fixtures/projects.yml +7 -7
  349. data/test/fixtures/ratings.yml +14 -14
  350. data/test/fixtures/readers.yml +11 -11
  351. data/test/fixtures/references.yml +17 -17
  352. data/test/fixtures/reserved_words/distinct.yml +5 -5
  353. data/test/fixtures/reserved_words/distinct_select.yml +11 -11
  354. data/test/fixtures/reserved_words/group.yml +14 -14
  355. data/test/fixtures/reserved_words/select.yml +8 -8
  356. data/test/fixtures/reserved_words/values.yml +7 -7
  357. data/test/fixtures/ships.yml +6 -6
  358. data/test/fixtures/speedometers.yml +8 -8
  359. data/test/fixtures/sponsors.yml +12 -12
  360. data/test/fixtures/string_key_objects.yml +7 -7
  361. data/test/fixtures/subscribers.yml +10 -10
  362. data/test/fixtures/subscriptions.yml +12 -12
  363. data/test/fixtures/taggings.yml +78 -78
  364. data/test/fixtures/tags.yml +11 -11
  365. data/test/fixtures/tasks.yml +7 -7
  366. data/test/fixtures/teapots.yml +3 -3
  367. data/test/fixtures/to_be_linked/accounts.yml +2 -2
  368. data/test/fixtures/to_be_linked/users.yml +10 -10
  369. data/test/fixtures/topics.yml +49 -49
  370. data/test/fixtures/toys.yml +14 -14
  371. data/test/fixtures/traffic_lights.yml +9 -9
  372. data/test/fixtures/treasures.yml +10 -10
  373. data/test/fixtures/trees.yml +3 -0
  374. data/test/fixtures/uuid_children.yml +3 -3
  375. data/test/fixtures/uuid_parents.yml +2 -2
  376. data/test/fixtures/variants.yml +4 -4
  377. data/test/fixtures/vegetables.yml +19 -19
  378. data/test/fixtures/vertices.yml +3 -3
  379. data/test/fixtures/warehouse_things.yml +2 -2
  380. data/test/fixtures/zines.yml +5 -5
  381. data/test/migrations/10_urban/9_add_expressions.rb +11 -11
  382. data/test/migrations/decimal/1_give_me_big_numbers.rb +15 -15
  383. data/test/migrations/magic/1_currencies_have_symbols.rb +12 -12
  384. data/test/migrations/missing/1000_people_have_middle_names.rb +9 -9
  385. data/test/migrations/missing/1_people_have_last_names.rb +9 -9
  386. data/test/migrations/missing/3_we_need_reminders.rb +12 -12
  387. data/test/migrations/missing/4_innocent_jointable.rb +12 -12
  388. data/test/migrations/rename/1_we_need_things.rb +11 -11
  389. data/test/migrations/rename/2_rename_things.rb +9 -9
  390. data/test/migrations/to_copy/1_people_have_hobbies.rb +9 -9
  391. data/test/migrations/to_copy/2_people_have_descriptions.rb +9 -9
  392. data/test/migrations/to_copy2/1_create_articles.rb +7 -7
  393. data/test/migrations/to_copy2/2_create_comments.rb +7 -7
  394. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +9 -9
  395. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +9 -9
  396. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +9 -9
  397. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +7 -7
  398. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +7 -7
  399. data/test/migrations/valid/1_valid_people_have_last_names.rb +9 -9
  400. data/test/migrations/valid/2_we_need_reminders.rb +12 -12
  401. data/test/migrations/valid/3_innocent_jointable.rb +12 -12
  402. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +9 -9
  403. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +12 -12
  404. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +12 -12
  405. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +9 -9
  406. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +12 -12
  407. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +12 -12
  408. data/test/migrations/version_check/20131219224947_migration_version_check.rb +8 -8
  409. data/test/models/admin.rb +5 -5
  410. data/test/models/admin/account.rb +3 -3
  411. data/test/models/admin/randomly_named_c1.rb +6 -2
  412. data/test/models/admin/user.rb +40 -40
  413. data/test/models/aircraft.rb +5 -4
  414. data/test/models/arunit2_model.rb +3 -3
  415. data/test/models/author.rb +209 -212
  416. data/test/models/auto_id.rb +4 -4
  417. data/test/models/autoloadable/extra_firm.rb +2 -2
  418. data/test/models/binary.rb +2 -2
  419. data/test/models/bird.rb +12 -12
  420. data/test/models/book.rb +23 -18
  421. data/test/models/boolean.rb +2 -2
  422. data/test/models/bulb.rb +52 -51
  423. data/test/models/cake_designer.rb +3 -3
  424. data/test/models/car.rb +29 -26
  425. data/test/models/carrier.rb +2 -2
  426. data/test/models/cat.rb +10 -0
  427. data/test/models/categorization.rb +19 -19
  428. data/test/models/category.rb +35 -35
  429. data/test/models/chef.rb +8 -7
  430. data/test/models/citation.rb +3 -3
  431. data/test/models/club.rb +25 -23
  432. data/test/models/college.rb +10 -10
  433. data/test/models/column.rb +3 -3
  434. data/test/models/column_name.rb +3 -3
  435. data/test/models/comment.rb +76 -64
  436. data/test/models/company.rb +230 -228
  437. data/test/models/company_in_module.rb +98 -98
  438. data/test/models/computer.rb +3 -3
  439. data/test/models/contact.rb +41 -41
  440. data/test/models/content.rb +40 -0
  441. data/test/models/contract.rb +20 -20
  442. data/test/models/country.rb +7 -7
  443. data/test/models/course.rb +6 -6
  444. data/test/models/customer.rb +83 -77
  445. data/test/models/customer_carrier.rb +14 -14
  446. data/test/models/dashboard.rb +3 -3
  447. data/test/models/default.rb +2 -2
  448. data/test/models/department.rb +4 -4
  449. data/test/models/developer.rb +274 -255
  450. data/test/models/dog.rb +5 -5
  451. data/test/models/dog_lover.rb +5 -5
  452. data/test/models/doubloon.rb +12 -12
  453. data/test/models/drink_designer.rb +3 -3
  454. data/test/models/edge.rb +5 -5
  455. data/test/models/electron.rb +5 -5
  456. data/test/models/engine.rb +4 -4
  457. data/test/models/entrant.rb +3 -3
  458. data/test/models/essay.rb +5 -5
  459. data/test/models/event.rb +3 -3
  460. data/test/models/eye.rb +37 -37
  461. data/test/models/face.rb +9 -9
  462. data/test/models/friendship.rb +6 -6
  463. data/test/models/guid.rb +2 -2
  464. data/test/models/guitar.rb +4 -0
  465. data/test/models/hotel.rb +11 -9
  466. data/test/models/image.rb +3 -3
  467. data/test/models/interest.rb +5 -5
  468. data/test/models/invoice.rb +4 -4
  469. data/test/models/item.rb +7 -7
  470. data/test/models/job.rb +7 -7
  471. data/test/models/joke.rb +7 -7
  472. data/test/models/keyboard.rb +3 -3
  473. data/test/models/legacy_thing.rb +3 -3
  474. data/test/models/lesson.rb +11 -11
  475. data/test/models/line_item.rb +3 -3
  476. data/test/models/liquid.rb +4 -4
  477. data/test/models/man.rb +11 -11
  478. data/test/models/matey.rb +4 -4
  479. data/test/models/member.rb +42 -41
  480. data/test/models/member_detail.rb +8 -7
  481. data/test/models/member_type.rb +3 -3
  482. data/test/models/membership.rb +35 -35
  483. data/test/models/mentor.rb +3 -0
  484. data/test/models/minimalistic.rb +2 -2
  485. data/test/models/minivan.rb +9 -9
  486. data/test/models/mixed_case_monkey.rb +3 -3
  487. data/test/models/mocktail_designer.rb +2 -0
  488. data/test/models/molecule.rb +6 -6
  489. data/test/models/movie.rb +5 -5
  490. data/test/models/node.rb +5 -0
  491. data/test/models/non_primary_key.rb +2 -0
  492. data/test/models/notification.rb +3 -0
  493. data/test/models/order.rb +4 -4
  494. data/test/models/organization.rb +14 -14
  495. data/test/models/other_dog.rb +5 -0
  496. data/test/models/owner.rb +37 -34
  497. data/test/models/parrot.rb +28 -29
  498. data/test/models/person.rb +142 -143
  499. data/test/models/personal_legacy_thing.rb +4 -4
  500. data/test/models/pet.rb +18 -15
  501. data/test/models/pet_treasure.rb +6 -0
  502. data/test/models/pirate.rb +92 -92
  503. data/test/models/possession.rb +3 -3
  504. data/test/models/post.rb +273 -264
  505. data/test/models/price_estimate.rb +4 -4
  506. data/test/models/professor.rb +5 -5
  507. data/test/models/project.rb +40 -31
  508. data/test/models/publisher.rb +2 -2
  509. data/test/models/publisher/article.rb +4 -4
  510. data/test/models/publisher/magazine.rb +3 -3
  511. data/test/models/randomly_named_c1.rb +1 -1
  512. data/test/models/rating.rb +4 -4
  513. data/test/models/reader.rb +23 -23
  514. data/test/models/recipe.rb +3 -0
  515. data/test/models/record.rb +2 -2
  516. data/test/models/reference.rb +22 -22
  517. data/test/models/reply.rb +61 -61
  518. data/test/models/ship.rb +39 -33
  519. data/test/models/ship_part.rb +8 -8
  520. data/test/models/shop.rb +17 -17
  521. data/test/models/shop_account.rb +6 -6
  522. data/test/models/speedometer.rb +6 -6
  523. data/test/models/sponsor.rb +7 -7
  524. data/test/models/string_key_object.rb +3 -3
  525. data/test/models/student.rb +4 -4
  526. data/test/models/subject.rb +16 -16
  527. data/test/models/subscriber.rb +8 -8
  528. data/test/models/subscription.rb +4 -4
  529. data/test/models/tag.rb +13 -7
  530. data/test/models/tagging.rb +13 -13
  531. data/test/models/task.rb +5 -5
  532. data/test/models/topic.rb +118 -124
  533. data/test/models/toy.rb +6 -6
  534. data/test/models/traffic_light.rb +4 -4
  535. data/test/models/treasure.rb +14 -14
  536. data/test/models/treaty.rb +7 -7
  537. data/test/models/tree.rb +3 -0
  538. data/test/models/tuning_peg.rb +4 -0
  539. data/test/models/tyre.rb +11 -11
  540. data/test/models/user.rb +14 -0
  541. data/test/models/uuid_child.rb +3 -3
  542. data/test/models/uuid_item.rb +6 -0
  543. data/test/models/uuid_parent.rb +3 -3
  544. data/test/models/vegetables.rb +24 -24
  545. data/test/models/vehicle.rb +6 -6
  546. data/test/models/vertex.rb +9 -9
  547. data/test/models/warehouse_thing.rb +5 -5
  548. data/test/models/wheel.rb +3 -3
  549. data/test/models/without_table.rb +3 -3
  550. data/test/models/zine.rb +3 -3
  551. data/test/schema/mysql2_specific_schema.rb +68 -58
  552. data/test/schema/oracle_specific_schema.rb +40 -43
  553. data/test/schema/postgresql_specific_schema.rb +114 -202
  554. data/test/schema/schema.rb +1057 -952
  555. data/test/schema/schema.rb.original +1057 -0
  556. data/test/schema/sqlite_specific_schema.rb +18 -22
  557. data/test/support/config.rb +43 -43
  558. data/test/support/connection.rb +23 -22
  559. data/test/support/connection_helper.rb +14 -14
  560. data/test/support/ddl_helper.rb +8 -8
  561. data/test/support/schema_dumping_helper.rb +20 -20
  562. data/test/support/yaml_compatibility_fixtures/rails_4_1.yml +22 -0
  563. data/test/support/yaml_compatibility_fixtures/rails_4_2_0.yml +182 -0
  564. metadata +129 -24
  565. data/test/cases/associations/deprecated_counter_cache_on_has_many_through_test.rb +0 -26
  566. data/test/cases/attribute_methods/serialization_test.rb +0 -29
  567. data/test/cases/migration/change_schema_test - Copy.rb +0 -448
  568. data/test/cases/migration/foreign_key_test - Changed.rb +0 -325
  569. data/test/cases/migration/table_and_index_test.rb +0 -24
  570. data/test/cases/relation/where_test2.rb +0 -36
  571. data/test/cases/type/decimal_test.rb +0 -56
  572. data/test/cases/type/unsigned_integer_test.rb +0 -18
  573. data/test/cases/xml_serialization_test.rb +0 -457
  574. data/test/connections/native_ibm_db/connection.rb +0 -44
  575. data/test/fixtures/naked/csv/accounts.csv +0 -1
  576. data/test/schema/i5/ibm_db_specific_schema.rb +0 -137
  577. data/test/schema/ids/ibm_db_specific_schema.rb +0 -140
  578. data/test/schema/luw/ibm_db_specific_schema.rb +0 -137
  579. data/test/schema/mysql_specific_schema.rb +0 -70
  580. data/test/schema/zOS/ibm_db_specific_schema.rb +0 -208
@@ -0,0 +1,121 @@
1
+ require 'cases/helper'
2
+ require 'models/invoice'
3
+ require 'models/line_item'
4
+ require 'models/topic'
5
+ require 'models/node'
6
+ require 'models/tree'
7
+
8
+ class TouchLaterTest < ActiveRecord::TestCase
9
+ fixtures :nodes, :trees
10
+
11
+ def test_touch_laster_raise_if_non_persisted
12
+ invoice = Invoice.new
13
+ Invoice.transaction do
14
+ assert_not invoice.persisted?
15
+ assert_raises(ActiveRecord::ActiveRecordError) do
16
+ invoice.touch_later
17
+ end
18
+ end
19
+ end
20
+
21
+ def test_touch_later_dont_set_dirty_attributes
22
+ invoice = Invoice.create!
23
+ invoice.touch_later
24
+ assert_not invoice.changed?
25
+ end
26
+
27
+ def test_touch_later_respects_no_touching_policy
28
+ time = Time.now.utc - 25.days
29
+ topic = Topic.create!(updated_at: time, created_at: time)
30
+ Topic.no_touching do
31
+ topic.touch_later
32
+ end
33
+ assert_equal time.to_i, topic.updated_at.to_i
34
+ end
35
+
36
+ def test_touch_later_update_the_attributes
37
+ time = Time.now.utc - 25.days
38
+ topic = Topic.create!(updated_at: time, created_at: time)
39
+ assert_equal time.to_i, topic.updated_at.to_i
40
+ assert_equal time.to_i, topic.created_at.to_i
41
+
42
+ Topic.transaction do
43
+ topic.touch_later(:created_at)
44
+ assert_not_equal time.to_i, topic.updated_at.to_i
45
+ assert_not_equal time.to_i, topic.created_at.to_i
46
+
47
+ assert_equal time.to_i, topic.reload.updated_at.to_i
48
+ assert_equal time.to_i, topic.reload.created_at.to_i
49
+ end
50
+ assert_not_equal time.to_i, topic.reload.updated_at.to_i
51
+ assert_not_equal time.to_i, topic.reload.created_at.to_i
52
+ end
53
+
54
+ def test_touch_touches_immediately
55
+ time = Time.now.utc - 25.days
56
+ topic = Topic.create!(updated_at: time, created_at: time)
57
+ assert_equal time.to_i, topic.updated_at.to_i
58
+ assert_equal time.to_i, topic.created_at.to_i
59
+
60
+ Topic.transaction do
61
+ topic.touch_later(:created_at)
62
+ topic.touch
63
+
64
+ assert_not_equal time, topic.reload.updated_at
65
+ assert_not_equal time, topic.reload.created_at
66
+ end
67
+ end
68
+
69
+ def test_touch_later_an_association_dont_autosave_parent
70
+ time = Time.now.utc - 25.days
71
+ line_item = LineItem.create!(amount: 1)
72
+ invoice = Invoice.create!(line_items: [line_item])
73
+ invoice.touch(time: time)
74
+
75
+ Invoice.transaction do
76
+ line_item.update(amount: 2)
77
+ assert_equal time.to_i, invoice.reload.updated_at.to_i
78
+ end
79
+
80
+ assert_not_equal time.to_i, invoice.updated_at.to_i
81
+ end
82
+
83
+ def test_touch_touches_immediately_with_a_custom_time
84
+ time = (Time.now.utc - 25.days).change(nsec: 0)
85
+ topic = Topic.create!(updated_at: time, created_at: time)
86
+ assert_equal time, topic.updated_at
87
+ assert_equal time, topic.created_at
88
+
89
+ Topic.transaction do
90
+ topic.touch_later(:created_at)
91
+ time = Time.now.utc - 2.days
92
+ topic.touch(time: time)
93
+
94
+ assert_equal time.to_i, topic.reload.updated_at.to_i
95
+ assert_equal time.to_i, topic.reload.created_at.to_i
96
+ end
97
+ end
98
+
99
+ def test_touch_later_dont_hit_the_db
100
+ invoice = Invoice.create!
101
+ assert_queries(0) do
102
+ invoice.touch_later
103
+ end
104
+ end
105
+
106
+ def test_touching_three_deep
107
+ previous_tree_updated_at = trees(:root).updated_at
108
+ previous_grandparent_updated_at = nodes(:grandparent).updated_at
109
+ previous_parent_updated_at = nodes(:parent_a).updated_at
110
+ previous_child_updated_at = nodes(:child_one_of_a).updated_at
111
+
112
+ travel 5.seconds do
113
+ Node.create! parent: nodes(:child_one_of_a), tree: trees(:root)
114
+ end
115
+
116
+ assert_not_equal nodes(:child_one_of_a).reload.updated_at, previous_child_updated_at
117
+ assert_not_equal nodes(:parent_a).reload.updated_at, previous_parent_updated_at
118
+ assert_not_equal nodes(:grandparent).reload.updated_at, previous_grandparent_updated_at
119
+ assert_not_equal trees(:root).reload.updated_at, previous_tree_updated_at
120
+ end
121
+ end
@@ -1,452 +1,518 @@
1
- require "cases/helper"
2
- require 'models/owner'
3
- require 'models/pet'
4
- require 'models/topic'
5
-
6
- class TransactionCallbacksTest < ActiveRecord::TestCase
7
- self.use_transactional_fixtures = false
8
- fixtures :topics, :owners, :pets
9
-
10
- class ReplyWithCallbacks < ActiveRecord::Base
11
- self.table_name = :topics
12
-
13
- belongs_to :topic, foreign_key: "parent_id"
14
-
15
- validates_presence_of :content
16
-
17
- after_commit :do_after_commit, on: :create
18
-
19
- attr_accessor :save_on_after_create
20
- after_create do
21
- self.save! if save_on_after_create
22
- end
23
-
24
- def history
25
- @history ||= []
26
- end
27
-
28
- def do_after_commit
29
- history << :commit_on_create
30
- end
31
- end
32
-
33
- class TopicWithCallbacks < ActiveRecord::Base
34
- self.table_name = :topics
35
-
36
- has_many :replies, class_name: "ReplyWithCallbacks", foreign_key: "parent_id"
37
-
38
- after_commit { |record| record.do_after_commit(nil) }
39
- after_commit(on: :create) { |record| record.do_after_commit(:create) }
40
- after_commit(on: :update) { |record| record.do_after_commit(:update) }
41
- after_commit(on: :destroy) { |record| record.do_after_commit(:destroy) }
42
- after_rollback { |record| record.do_after_rollback(nil) }
43
- after_rollback(on: :create) { |record| record.do_after_rollback(:create) }
44
- after_rollback(on: :update) { |record| record.do_after_rollback(:update) }
45
- after_rollback(on: :destroy) { |record| record.do_after_rollback(:destroy) }
46
-
47
- def history
48
- @history ||= []
49
- end
50
-
51
- def after_commit_block(on = nil, &block)
52
- @after_commit ||= {}
53
- @after_commit[on] ||= []
54
- @after_commit[on] << block
55
- end
56
-
57
- def after_rollback_block(on = nil, &block)
58
- @after_rollback ||= {}
59
- @after_rollback[on] ||= []
60
- @after_rollback[on] << block
61
- end
62
-
63
- def do_after_commit(on)
64
- blocks = @after_commit[on] if defined?(@after_commit)
65
- blocks.each{|b| b.call(self)} if blocks
66
- end
67
-
68
- def do_after_rollback(on)
69
- blocks = @after_rollback[on] if defined?(@after_rollback)
70
- blocks.each{|b| b.call(self)} if blocks
71
- end
72
- end
73
-
74
- def setup
75
- @first = TopicWithCallbacks.find(1)
76
- end
77
-
78
- def test_call_after_commit_after_transaction_commits
79
- @first.after_commit_block{|r| r.history << :after_commit}
80
- @first.after_rollback_block{|r| r.history << :after_rollback}
81
-
82
- @first.save!
83
- assert_equal [:after_commit], @first.history
84
- end
85
-
86
- def test_only_call_after_commit_on_update_after_transaction_commits_for_existing_record
87
- add_transaction_execution_blocks @first
88
-
89
- @first.save!
90
- assert_equal [:commit_on_update], @first.history
91
- end
92
-
93
- def test_only_call_after_commit_on_destroy_after_transaction_commits_for_destroyed_record
94
- add_transaction_execution_blocks @first
95
-
96
- @first.destroy
97
- assert_equal [:commit_on_destroy], @first.history
98
- end
99
-
100
- def test_only_call_after_commit_on_create_after_transaction_commits_for_new_record
101
- unless current_adapter?(:IBM_DBAdapter)
102
- @new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Date.today)
103
- else
104
- @new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Time.now)
105
- end
106
- add_transaction_execution_blocks new_record
107
-
108
- new_record.save!
109
- assert_equal [:commit_on_create], new_record.history
110
- end
111
-
112
- def test_only_call_after_commit_on_create_after_transaction_commits_for_new_record_if_create_succeeds_creating_through_association
113
- topic = TopicWithCallbacks.create!(:title => "New topic", :written_on => Date.today)
114
- reply = topic.replies.create
115
-
116
- assert_equal [], reply.history
117
- end
118
-
119
- def test_only_call_after_commit_on_create_and_doesnt_leaky
120
- r = ReplyWithCallbacks.new(content: 'foo')
121
- r.save_on_after_create = true
122
- r.save!
123
- r.content = 'bar'
124
- r.save!
125
- r.save!
126
- assert_equal [:commit_on_create], r.history
127
- end
128
-
129
- def test_only_call_after_commit_on_update_after_transaction_commits_for_existing_record_on_touch
130
- add_transaction_execution_blocks @first
131
-
132
- @first.touch
133
- assert_equal [:commit_on_update], @first.history
134
- end
135
-
136
- def test_only_call_after_commit_on_top_level_transactions
137
- @first.after_commit_block{|r| r.history << :after_commit}
138
- assert @first.history.empty?
139
-
140
- @first.transaction do
141
- @first.transaction(requires_new: true) do
142
- @first.touch
143
- end
144
- assert @first.history.empty?
145
- end
146
- assert_equal [:after_commit], @first.history
147
- end
148
-
149
- def test_call_after_rollback_after_transaction_rollsback
150
- @first.after_commit_block{|r| r.history << :after_commit}
151
- @first.after_rollback_block{|r| r.history << :after_rollback}
152
-
153
- Topic.transaction do
154
- @first.save!
155
- raise ActiveRecord::Rollback
156
- end
157
-
158
- assert_equal [:after_rollback], @first.history
159
- end
160
-
161
- def test_only_call_after_rollback_on_update_after_transaction_rollsback_for_existing_record
162
- add_transaction_execution_blocks @first
163
-
164
- Topic.transaction do
165
- @first.save!
166
- raise ActiveRecord::Rollback
167
- end
168
-
169
- assert_equal [:rollback_on_update], @first.history
170
- end
171
-
172
- def test_only_call_after_rollback_on_update_after_transaction_rollsback_for_existing_record_on_touch
173
- add_transaction_execution_blocks @first
174
-
175
- Topic.transaction do
176
- @first.touch
177
- raise ActiveRecord::Rollback
178
- end
179
-
180
- assert_equal [:rollback_on_update], @first.history
181
- end
182
-
183
- def test_only_call_after_rollback_on_destroy_after_transaction_rollsback_for_destroyed_record
184
- add_transaction_execution_blocks @first
185
-
186
- Topic.transaction do
187
- @first.destroy
188
- raise ActiveRecord::Rollback
189
- end
190
-
191
- assert_equal [:rollback_on_destroy], @first.history
192
- end
193
-
194
- def test_only_call_after_rollback_on_create_after_transaction_rollsback_for_new_record
195
- unless current_adapter?(:IBM_DBAdapter)
196
- @new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Date.today)
197
- else
198
- @new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Time.now)
199
- end
200
- add_transaction_execution_blocks new_record
201
-
202
- Topic.transaction do
203
- new_record.save!
204
- raise ActiveRecord::Rollback
205
- end
206
-
207
- assert_equal [:rollback_on_create], new_record.history
208
- end
209
-
210
- def test_call_after_rollback_when_commit_fails
211
- @first.class.connection.singleton_class.send(:alias_method, :real_method_commit_db_transaction, :commit_db_transaction)
212
- begin
213
- @first.class.connection.singleton_class.class_eval do
214
- def commit_db_transaction; raise "boom!"; end
215
- end
216
-
217
- @first.after_commit_block{|r| r.history << :after_commit}
218
- @first.after_rollback_block{|r| r.history << :after_rollback}
219
-
220
- assert !@first.save rescue nil
221
- assert_equal [:after_rollback], @first.history
222
- ensure
223
- @first.class.connection.singleton_class.send(:remove_method, :commit_db_transaction)
224
- @first.class.connection.singleton_class.send(:alias_method, :commit_db_transaction, :real_method_commit_db_transaction)
225
- end
226
- end
227
-
228
- def test_only_call_after_rollback_on_records_rolled_back_to_a_savepoint
229
- def @first.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
230
- def @first.commits(i=0); @commits ||= 0; @commits += i if i; end
231
- @first.after_rollback_block{|r| r.rollbacks(1)}
232
- @first.after_commit_block{|r| r.commits(1)}
233
-
234
- second = TopicWithCallbacks.find(3)
235
- def second.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
236
- def second.commits(i=0); @commits ||= 0; @commits += i if i; end
237
- second.after_rollback_block{|r| r.rollbacks(1)}
238
- second.after_commit_block{|r| r.commits(1)}
239
-
240
- Topic.transaction do
241
- @first.save!
242
- Topic.transaction(:requires_new => true) do
243
- second.save!
244
- raise ActiveRecord::Rollback
245
- end
246
- end
247
-
248
- assert_equal 1, @first.commits
249
- assert_equal 0, @first.rollbacks
250
- assert_equal 0, second.commits
251
- assert_equal 1, second.rollbacks
252
- end
253
-
254
- def test_only_call_after_rollback_on_records_rolled_back_to_a_savepoint_when_release_savepoint_fails
255
- def @first.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
256
- def @first.commits(i=0); @commits ||= 0; @commits += i if i; end
257
-
258
- @first.after_rollback_block{|r| r.rollbacks(1)}
259
- @first.after_commit_block{|r| r.commits(1)}
260
-
261
- Topic.transaction do
262
- @first.save
263
- Topic.transaction(:requires_new => true) do
264
- @first.save!
265
- raise ActiveRecord::Rollback
266
- end
267
- Topic.transaction(:requires_new => true) do
268
- @first.save!
269
- raise ActiveRecord::Rollback
270
- end
271
- end
272
-
273
- assert_equal 1, @first.commits
274
- assert_equal 2, @first.rollbacks
275
- end
276
-
277
- def test_after_transaction_callbacks_should_prevent_callbacks_from_being_called
278
- old_transaction_config = ActiveRecord::Base.raise_in_transactional_callbacks
279
- ActiveRecord::Base.raise_in_transactional_callbacks = false
280
-
281
- def @first.last_after_transaction_error=(e); @last_transaction_error = e; end
282
- def @first.last_after_transaction_error; @last_transaction_error; end
283
- @first.after_commit_block{|r| r.last_after_transaction_error = :commit; raise "fail!";}
284
- @first.after_rollback_block{|r| r.last_after_transaction_error = :rollback; raise "fail!";}
285
-
286
- second = TopicWithCallbacks.find(3)
287
- second.after_commit_block{|r| r.history << :after_commit}
288
- second.after_rollback_block{|r| r.history << :after_rollback}
289
-
290
- Topic.transaction do
291
- @first.save!
292
- second.save!
293
- end
294
- assert_equal :commit, @first.last_after_transaction_error
295
- assert_equal [:after_commit], second.history
296
-
297
- second.history.clear
298
- Topic.transaction do
299
- @first.save!
300
- second.save!
301
- raise ActiveRecord::Rollback
302
- end
303
- assert_equal :rollback, @first.last_after_transaction_error
304
- assert_equal [:after_rollback], second.history
305
- ensure
306
- ActiveRecord::Base.raise_in_transactional_callbacks = old_transaction_config
307
- end
308
-
309
- def test_after_commit_should_not_raise_when_raise_in_transactional_callbacks_false
310
- old_transaction_config = ActiveRecord::Base.raise_in_transactional_callbacks
311
- ActiveRecord::Base.raise_in_transactional_callbacks = false
312
- @first.after_commit_block{ fail "boom" }
313
- Topic.transaction { @first.save! }
314
- ensure
315
- ActiveRecord::Base.raise_in_transactional_callbacks = old_transaction_config
316
- end
317
-
318
- def test_after_commit_callback_should_not_swallow_errors
319
- @first.after_commit_block{ fail "boom" }
320
- assert_raises(RuntimeError) do
321
- Topic.transaction do
322
- @first.save!
323
- end
324
- end
325
- end
326
-
327
- def test_after_commit_callback_when_raise_should_not_restore_state
328
- first = TopicWithCallbacks.new
329
- second = TopicWithCallbacks.new
330
- first.after_commit_block{ fail "boom" }
331
- second.after_commit_block{ fail "boom" }
332
-
333
- begin
334
- Topic.transaction do
335
- first.save!
336
- assert_not_nil first.id
337
- second.save!
338
- assert_not_nil second.id
339
- end
340
- rescue
341
- end
342
- assert_not_nil first.id
343
- assert_not_nil second.id
344
- assert first.reload
345
- end
346
-
347
- def test_after_rollback_callback_should_not_swallow_errors_when_set_to_raise
348
- error_class = Class.new(StandardError)
349
- @first.after_rollback_block{ raise error_class }
350
- assert_raises(error_class) do
351
- Topic.transaction do
352
- @first.save!
353
- raise ActiveRecord::Rollback
354
- end
355
- end
356
- end
357
-
358
- def test_after_rollback_callback_when_raise_should_restore_state
359
- error_class = Class.new(StandardError)
360
-
361
- first = TopicWithCallbacks.new
362
- second = TopicWithCallbacks.new
363
- first.after_rollback_block{ raise error_class }
364
- second.after_rollback_block{ raise error_class }
365
-
366
- begin
367
- Topic.transaction do
368
- first.save!
369
- assert_not_nil first.id
370
- second.save!
371
- assert_not_nil second.id
372
- raise ActiveRecord::Rollback
373
- end
374
- rescue error_class
375
- end
376
- assert_nil first.id
377
- assert_nil second.id
378
- end
379
-
380
- def test_after_rollback_callbacks_should_validate_on_condition
381
- assert_raise(ArgumentError) { Topic.after_rollback(on: :save) }
382
- e = assert_raise(ArgumentError) { Topic.after_rollback(on: 'create') }
383
- assert_match(/:on conditions for after_commit and after_rollback callbacks have to be one of \[:create, :destroy, :update\]/, e.message)
384
- end
385
-
386
- def test_after_commit_callbacks_should_validate_on_condition
387
- assert_raise(ArgumentError) { Topic.after_commit(on: :save) }
388
- e = assert_raise(ArgumentError) { Topic.after_commit(on: 'create') }
389
- assert_match(/:on conditions for after_commit and after_rollback callbacks have to be one of \[:create, :destroy, :update\]/, e.message)
390
- end
391
-
392
- def test_saving_a_record_with_a_belongs_to_that_specifies_touching_the_parent_should_call_callbacks_on_the_parent_object
393
- pet = Pet.first
394
- owner = pet.owner
395
- flag = false
396
-
397
- owner.on_after_commit do
398
- flag = true
399
- end
400
-
401
- pet.name = "Fluffy the Third"
402
- pet.save
403
-
404
- assert flag
405
- end
406
-
407
- private
408
-
409
- def add_transaction_execution_blocks(record)
410
- record.after_commit_block(:create) { |r| r.history << :commit_on_create }
411
- record.after_commit_block(:update) { |r| r.history << :commit_on_update }
412
- record.after_commit_block(:destroy) { |r| r.history << :commit_on_destroy }
413
- record.after_rollback_block(:create) { |r| r.history << :rollback_on_create }
414
- record.after_rollback_block(:update) { |r| r.history << :rollback_on_update }
415
- record.after_rollback_block(:destroy) { |r| r.history << :rollback_on_destroy }
416
- end
417
- end
418
-
419
- class CallbacksOnMultipleActionsTest < ActiveRecord::TestCase
420
- self.use_transactional_fixtures = false
421
-
422
- class TopicWithCallbacksOnMultipleActions < ActiveRecord::Base
423
- self.table_name = :topics
424
-
425
- after_commit(on: [:create, :destroy]) { |record| record.history << :create_and_destroy }
426
- after_commit(on: [:create, :update]) { |record| record.history << :create_and_update }
427
- after_commit(on: [:update, :destroy]) { |record| record.history << :update_and_destroy }
428
-
429
- def clear_history
430
- @history = []
431
- end
432
-
433
- def history
434
- @history ||= []
435
- end
436
- end
437
-
438
- def test_after_commit_on_multiple_actions
439
- topic = TopicWithCallbacksOnMultipleActions.new
440
- topic.save
441
- assert_equal [:create_and_update, :create_and_destroy], topic.history
442
-
443
- topic.clear_history
444
- topic.approved = true
445
- topic.save
446
- assert_equal [:update_and_destroy, :create_and_update], topic.history
447
-
448
- topic.clear_history
449
- topic.destroy
450
- assert_equal [:update_and_destroy, :create_and_destroy], topic.history
451
- end
452
- end
1
+ require "cases/helper"
2
+ require 'models/owner'
3
+ require 'models/pet'
4
+ require 'models/topic'
5
+
6
+ class TransactionCallbacksTest < ActiveRecord::TestCase
7
+ fixtures :topics, :owners, :pets
8
+
9
+ class ReplyWithCallbacks < ActiveRecord::Base
10
+ self.table_name = :topics
11
+
12
+ belongs_to :topic, foreign_key: "parent_id"
13
+
14
+ validates_presence_of :content
15
+
16
+ after_commit :do_after_commit, on: :create
17
+
18
+ attr_accessor :save_on_after_create
19
+ after_create do
20
+ self.save! if save_on_after_create
21
+ end
22
+
23
+ def history
24
+ @history ||= []
25
+ end
26
+
27
+ def do_after_commit
28
+ history << :commit_on_create
29
+ end
30
+ end
31
+
32
+ class TopicWithCallbacks < ActiveRecord::Base
33
+ self.table_name = :topics
34
+
35
+ has_many :replies, class_name: "ReplyWithCallbacks", foreign_key: "parent_id"
36
+
37
+ before_commit { |record| record.do_before_commit(nil) }
38
+ after_commit { |record| record.do_after_commit(nil) }
39
+ after_create_commit { |record| record.do_after_commit(:create) }
40
+ after_update_commit { |record| record.do_after_commit(:update) }
41
+ after_destroy_commit { |record| record.do_after_commit(:destroy) }
42
+ after_rollback { |record| record.do_after_rollback(nil) }
43
+ after_rollback(on: :create) { |record| record.do_after_rollback(:create) }
44
+ after_rollback(on: :update) { |record| record.do_after_rollback(:update) }
45
+ after_rollback(on: :destroy) { |record| record.do_after_rollback(:destroy) }
46
+
47
+ def history
48
+ @history ||= []
49
+ end
50
+
51
+ def before_commit_block(on = nil, &block)
52
+ @before_commit ||= {}
53
+ @before_commit[on] ||= []
54
+ @before_commit[on] << block
55
+ end
56
+
57
+ def after_commit_block(on = nil, &block)
58
+ @after_commit ||= {}
59
+ @after_commit[on] ||= []
60
+ @after_commit[on] << block
61
+ end
62
+
63
+ def after_rollback_block(on = nil, &block)
64
+ @after_rollback ||= {}
65
+ @after_rollback[on] ||= []
66
+ @after_rollback[on] << block
67
+ end
68
+
69
+ def do_before_commit(on)
70
+ blocks = @before_commit[on] if defined?(@before_commit)
71
+ blocks.each{|b| b.call(self)} if blocks
72
+ end
73
+
74
+ def do_after_commit(on)
75
+ blocks = @after_commit[on] if defined?(@after_commit)
76
+ blocks.each{|b| b.call(self)} if blocks
77
+ end
78
+
79
+ def do_after_rollback(on)
80
+ blocks = @after_rollback[on] if defined?(@after_rollback)
81
+ blocks.each{|b| b.call(self)} if blocks
82
+ end
83
+ end
84
+
85
+ def setup
86
+ @first = TopicWithCallbacks.find(1)
87
+ end
88
+
89
+ # FIXME: Test behavior, not implementation.
90
+ def test_before_commit_exception_should_pop_transaction_stack
91
+ @first.before_commit_block { raise 'better pop this txn from the stack!' }
92
+
93
+ original_txn = @first.class.connection.current_transaction
94
+
95
+ begin
96
+ @first.save!
97
+ fail
98
+ rescue
99
+ assert_equal original_txn, @first.class.connection.current_transaction
100
+ end
101
+ end
102
+
103
+ def test_call_after_commit_after_transaction_commits
104
+ @first.after_commit_block{|r| r.history << :after_commit}
105
+ @first.after_rollback_block{|r| r.history << :after_rollback}
106
+
107
+ @first.save!
108
+ assert_equal [:after_commit], @first.history
109
+ end
110
+
111
+ def test_only_call_after_commit_on_update_after_transaction_commits_for_existing_record
112
+ add_transaction_execution_blocks @first
113
+
114
+ @first.save!
115
+ assert_equal [:commit_on_update], @first.history
116
+ end
117
+
118
+ def test_only_call_after_commit_on_destroy_after_transaction_commits_for_destroyed_record
119
+ add_transaction_execution_blocks @first
120
+
121
+ @first.destroy
122
+ assert_equal [:commit_on_destroy], @first.history
123
+ end
124
+
125
+ def test_only_call_after_commit_on_create_after_transaction_commits_for_new_record
126
+ unless current_adapter?(:IBM_DBAdapter)
127
+ new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Date.today)
128
+ else
129
+ new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Time.now)
130
+ end
131
+ add_transaction_execution_blocks new_record
132
+
133
+ new_record.save!
134
+ assert_equal [:commit_on_create], new_record.history
135
+ end
136
+
137
+ def test_only_call_after_commit_on_create_after_transaction_commits_for_new_record_if_create_succeeds_creating_through_association
138
+ topic = TopicWithCallbacks.create!(:title => "New topic", :written_on => Date.today)
139
+ reply = topic.replies.create
140
+
141
+ assert_equal [], reply.history
142
+ end
143
+
144
+ def test_only_call_after_commit_on_create_and_doesnt_leaky
145
+ r = ReplyWithCallbacks.new(content: 'foo')
146
+ r.save_on_after_create = true
147
+ r.save!
148
+ r.content = 'bar'
149
+ r.save!
150
+ r.save!
151
+ assert_equal [:commit_on_create], r.history
152
+ end
153
+
154
+ def test_only_call_after_commit_on_update_after_transaction_commits_for_existing_record_on_touch
155
+ add_transaction_execution_blocks @first
156
+
157
+ @first.touch
158
+ assert_equal [:commit_on_update], @first.history
159
+ end
160
+
161
+ def test_only_call_after_commit_on_top_level_transactions
162
+ @first.after_commit_block{|r| r.history << :after_commit}
163
+ assert @first.history.empty?
164
+
165
+ @first.transaction do
166
+ @first.transaction(requires_new: true) do
167
+ @first.touch
168
+ end
169
+ assert @first.history.empty?
170
+ end
171
+ assert_equal [:after_commit], @first.history
172
+ end
173
+
174
+ def test_call_after_rollback_after_transaction_rollsback
175
+ @first.after_commit_block{|r| r.history << :after_commit}
176
+ @first.after_rollback_block{|r| r.history << :after_rollback}
177
+
178
+ Topic.transaction do
179
+ @first.save!
180
+ raise ActiveRecord::Rollback
181
+ end
182
+
183
+ assert_equal [:after_rollback], @first.history
184
+ end
185
+
186
+ def test_only_call_after_rollback_on_update_after_transaction_rollsback_for_existing_record
187
+ add_transaction_execution_blocks @first
188
+
189
+ Topic.transaction do
190
+ @first.save!
191
+ raise ActiveRecord::Rollback
192
+ end
193
+
194
+ assert_equal [:rollback_on_update], @first.history
195
+ end
196
+
197
+ def test_only_call_after_rollback_on_update_after_transaction_rollsback_for_existing_record_on_touch
198
+ add_transaction_execution_blocks @first
199
+
200
+ Topic.transaction do
201
+ @first.touch
202
+ raise ActiveRecord::Rollback
203
+ end
204
+
205
+ assert_equal [:rollback_on_update], @first.history
206
+ end
207
+
208
+ def test_only_call_after_rollback_on_destroy_after_transaction_rollsback_for_destroyed_record
209
+ add_transaction_execution_blocks @first
210
+
211
+ Topic.transaction do
212
+ @first.destroy
213
+ raise ActiveRecord::Rollback
214
+ end
215
+
216
+ assert_equal [:rollback_on_destroy], @first.history
217
+ end
218
+
219
+ def test_only_call_after_rollback_on_create_after_transaction_rollsback_for_new_record
220
+ unless current_adapter?(:IBM_DBAdapter)
221
+ new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Date.today)
222
+ else
223
+ new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Time.now)
224
+ end
225
+ add_transaction_execution_blocks new_record
226
+
227
+ Topic.transaction do
228
+ new_record.save!
229
+ raise ActiveRecord::Rollback
230
+ end
231
+
232
+ assert_equal [:rollback_on_create], new_record.history
233
+ end
234
+
235
+ def test_call_after_rollback_when_commit_fails
236
+ @first.after_commit_block { |r| r.history << :after_commit }
237
+ @first.after_rollback_block { |r| r.history << :after_rollback }
238
+
239
+ assert_raises RuntimeError do
240
+ @first.transaction do
241
+ tx = @first.class.connection.transaction_manager.current_transaction
242
+ def tx.commit
243
+ raise
244
+ end
245
+
246
+ @first.save
247
+ end
248
+ end
249
+
250
+ assert_equal [:after_rollback], @first.history
251
+ end
252
+
253
+ def test_only_call_after_rollback_on_records_rolled_back_to_a_savepoint
254
+ def @first.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
255
+ def @first.commits(i=0); @commits ||= 0; @commits += i if i; end
256
+ @first.after_rollback_block{|r| r.rollbacks(1)}
257
+ @first.after_commit_block{|r| r.commits(1)}
258
+
259
+ second = TopicWithCallbacks.find(3)
260
+ def second.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
261
+ def second.commits(i=0); @commits ||= 0; @commits += i if i; end
262
+ second.after_rollback_block{|r| r.rollbacks(1)}
263
+ second.after_commit_block{|r| r.commits(1)}
264
+
265
+ Topic.transaction do
266
+ @first.save!
267
+ Topic.transaction(:requires_new => true) do
268
+ second.save!
269
+ raise ActiveRecord::Rollback
270
+ end
271
+ end
272
+
273
+ assert_equal 1, @first.commits
274
+ assert_equal 0, @first.rollbacks
275
+ assert_equal 0, second.commits
276
+ assert_equal 1, second.rollbacks
277
+ end
278
+
279
+ def test_only_call_after_rollback_on_records_rolled_back_to_a_savepoint_when_release_savepoint_fails
280
+ def @first.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
281
+ def @first.commits(i=0); @commits ||= 0; @commits += i if i; end
282
+
283
+ @first.after_rollback_block{|r| r.rollbacks(1)}
284
+ @first.after_commit_block{|r| r.commits(1)}
285
+
286
+ Topic.transaction do
287
+ @first.save
288
+ Topic.transaction(:requires_new => true) do
289
+ @first.save!
290
+ raise ActiveRecord::Rollback
291
+ end
292
+ Topic.transaction(:requires_new => true) do
293
+ @first.save!
294
+ raise ActiveRecord::Rollback
295
+ end
296
+ end
297
+
298
+ assert_equal 1, @first.commits
299
+ assert_equal 2, @first.rollbacks
300
+ end
301
+
302
+ def test_after_commit_callback_should_not_swallow_errors
303
+ @first.after_commit_block{ fail "boom" }
304
+ assert_raises(RuntimeError) do
305
+ Topic.transaction do
306
+ @first.save!
307
+ end
308
+ end
309
+ end
310
+
311
+ def test_after_commit_callback_when_raise_should_not_restore_state
312
+ first = TopicWithCallbacks.new
313
+ second = TopicWithCallbacks.new
314
+ first.after_commit_block{ fail "boom" }
315
+ second.after_commit_block{ fail "boom" }
316
+
317
+ begin
318
+ Topic.transaction do
319
+ first.save!
320
+ assert_not_nil first.id
321
+ second.save!
322
+ assert_not_nil second.id
323
+ end
324
+ rescue
325
+ end
326
+ assert_not_nil first.id
327
+ assert_not_nil second.id
328
+ assert first.reload
329
+ end
330
+
331
+ def test_after_rollback_callback_should_not_swallow_errors_when_set_to_raise
332
+ error_class = Class.new(StandardError)
333
+ @first.after_rollback_block{ raise error_class }
334
+ assert_raises(error_class) do
335
+ Topic.transaction do
336
+ @first.save!
337
+ raise ActiveRecord::Rollback
338
+ end
339
+ end
340
+ end
341
+
342
+ def test_after_rollback_callback_when_raise_should_restore_state
343
+ error_class = Class.new(StandardError)
344
+
345
+ first = TopicWithCallbacks.new
346
+ second = TopicWithCallbacks.new
347
+ first.after_rollback_block{ raise error_class }
348
+ second.after_rollback_block{ raise error_class }
349
+
350
+ begin
351
+ Topic.transaction do
352
+ first.save!
353
+ assert_not_nil first.id
354
+ second.save!
355
+ assert_not_nil second.id
356
+ raise ActiveRecord::Rollback
357
+ end
358
+ rescue error_class
359
+ end
360
+ assert_nil first.id
361
+ assert_nil second.id
362
+ end
363
+
364
+ def test_after_rollback_callbacks_should_validate_on_condition
365
+ assert_raise(ArgumentError) { Topic.after_rollback(on: :save) }
366
+ e = assert_raise(ArgumentError) { Topic.after_rollback(on: 'create') }
367
+ assert_match(/:on conditions for after_commit and after_rollback callbacks have to be one of \[:create, :destroy, :update\]/, e.message)
368
+ end
369
+
370
+ def test_after_commit_callbacks_should_validate_on_condition
371
+ assert_raise(ArgumentError) { Topic.after_commit(on: :save) }
372
+ e = assert_raise(ArgumentError) { Topic.after_commit(on: 'create') }
373
+ assert_match(/:on conditions for after_commit and after_rollback callbacks have to be one of \[:create, :destroy, :update\]/, e.message)
374
+ end
375
+
376
+ def test_saving_a_record_with_a_belongs_to_that_specifies_touching_the_parent_should_call_callbacks_on_the_parent_object
377
+ pet = Pet.first
378
+ owner = pet.owner
379
+ flag = false
380
+
381
+ owner.on_after_commit do
382
+ flag = true
383
+ end
384
+
385
+ pet.name = "Fluffy the Third"
386
+ pet.save
387
+
388
+ assert flag
389
+ end
390
+
391
+ private
392
+
393
+ def add_transaction_execution_blocks(record)
394
+ record.after_commit_block(:create) { |r| r.history << :commit_on_create }
395
+ record.after_commit_block(:update) { |r| r.history << :commit_on_update }
396
+ record.after_commit_block(:destroy) { |r| r.history << :commit_on_destroy }
397
+ record.after_rollback_block(:create) { |r| r.history << :rollback_on_create }
398
+ record.after_rollback_block(:update) { |r| r.history << :rollback_on_update }
399
+ record.after_rollback_block(:destroy) { |r| r.history << :rollback_on_destroy }
400
+ end
401
+ end
402
+
403
+ class CallbacksOnMultipleActionsTest < ActiveRecord::TestCase
404
+ self.use_transactional_tests = false
405
+
406
+ class TopicWithCallbacksOnMultipleActions < ActiveRecord::Base
407
+ self.table_name = :topics
408
+
409
+ after_commit(on: [:create, :destroy]) { |record| record.history << :create_and_destroy }
410
+ after_commit(on: [:create, :update]) { |record| record.history << :create_and_update }
411
+ after_commit(on: [:update, :destroy]) { |record| record.history << :update_and_destroy }
412
+
413
+ before_commit(if: :save_before_commit_history) { |record| record.history << :before_commit }
414
+ before_commit(if: :update_title) { |record| record.update(title: "before commit title") }
415
+
416
+ def clear_history
417
+ @history = []
418
+ end
419
+
420
+ def history
421
+ @history ||= []
422
+ end
423
+
424
+ attr_accessor :save_before_commit_history, :update_title
425
+ end
426
+
427
+ def test_after_commit_on_multiple_actions
428
+ topic = TopicWithCallbacksOnMultipleActions.new
429
+ topic.save
430
+ assert_equal [:create_and_update, :create_and_destroy], topic.history
431
+
432
+ topic.clear_history
433
+ topic.approved = true
434
+ topic.save
435
+ assert_equal [:update_and_destroy, :create_and_update], topic.history
436
+
437
+ topic.clear_history
438
+ topic.destroy
439
+ assert_equal [:update_and_destroy, :create_and_destroy], topic.history
440
+ end
441
+
442
+ def test_before_commit_actions
443
+ topic = TopicWithCallbacksOnMultipleActions.new
444
+ topic.save_before_commit_history = true
445
+ topic.save
446
+
447
+ assert_equal [:before_commit, :create_and_update, :create_and_destroy], topic.history
448
+ end
449
+
450
+ def test_before_commit_update_in_same_transaction
451
+ topic = TopicWithCallbacksOnMultipleActions.new
452
+ topic.update_title = true
453
+ topic.save
454
+
455
+ assert_equal "before commit title", topic.title
456
+ assert_equal "before commit title", topic.reload.title
457
+ end
458
+ end
459
+
460
+
461
+ class TransactionEnrollmentCallbacksTest < ActiveRecord::TestCase
462
+
463
+ class TopicWithoutTransactionalEnrollmentCallbacks < ActiveRecord::Base
464
+ self.table_name = :topics
465
+
466
+ before_commit_without_transaction_enrollment { |r| r.history << :before_commit }
467
+ after_commit_without_transaction_enrollment { |r| r.history << :after_commit }
468
+ after_rollback_without_transaction_enrollment { |r| r.history << :rollback }
469
+
470
+ def history
471
+ @history ||= []
472
+ end
473
+ end
474
+
475
+ def setup
476
+ @topic = TopicWithoutTransactionalEnrollmentCallbacks.create!
477
+ end
478
+
479
+ def test_commit_does_not_run_transactions_callbacks_without_enrollment
480
+ @topic.transaction do
481
+ @topic.content = 'foo'
482
+ @topic.save!
483
+ end
484
+ assert @topic.history.empty?
485
+ end
486
+
487
+ def test_commit_run_transactions_callbacks_with_explicit_enrollment
488
+ @topic.transaction do
489
+ 2.times do
490
+ @topic.content = 'foo'
491
+ @topic.save!
492
+ end
493
+ @topic.class.connection.add_transaction_record(@topic)
494
+ end
495
+ assert_equal [:before_commit, :after_commit], @topic.history
496
+ end
497
+
498
+ def test_rollback_does_not_run_transactions_callbacks_without_enrollment
499
+ @topic.transaction do
500
+ @topic.content = 'foo'
501
+ @topic.save!
502
+ raise ActiveRecord::Rollback
503
+ end
504
+ assert @topic.history.empty?
505
+ end
506
+
507
+ def test_rollback_run_transactions_callbacks_with_explicit_enrollment
508
+ @topic.transaction do
509
+ 2.times do
510
+ @topic.content = 'foo'
511
+ @topic.save!
512
+ end
513
+ @topic.class.connection.add_transaction_record(@topic)
514
+ raise ActiveRecord::Rollback
515
+ end
516
+ assert_equal [:rollback], @topic.history
517
+ end
518
+ end