ibm_db 5.2.0-x86-mingw32 → 5.3.2-x86-mingw32

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 (621) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +9 -0
  3. data/LICENSE +55 -18
  4. data/ext/Makefile +15 -13
  5. data/ext/ibm_db.c +62 -57
  6. data/ext/ibm_db.o +0 -0
  7. data/ext/ibm_db.so +0 -0
  8. data/ext/mkmf.log +26 -24
  9. data/ext/ruby_ibm_db_cli.c +1 -0
  10. data/ext/ruby_ibm_db_cli.o +0 -0
  11. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1463 -1279
  12. data/lib/ibm_db.so +1 -0
  13. data/lib/mswin32/rb3x/i386/ruby30/ibm_db.so +0 -0
  14. data/test/active_record/connection_adapters/fake_adapter.rb +5 -2
  15. data/test/activejob/destroy_association_async_test.rb +305 -0
  16. data/test/activejob/destroy_async_job_not_present_test.rb +31 -0
  17. data/test/activejob/helper.rb +15 -0
  18. data/test/assets/schema_dump_5_1.yml +345 -0
  19. data/test/cases/adapter_prevent_writes_test.rb +334 -0
  20. data/test/cases/adapter_test.rb +432 -218
  21. data/test/cases/adapters/mysql2/active_schema_test.rb +85 -75
  22. data/test/cases/adapters/mysql2/auto_increment_test.rb +34 -0
  23. data/test/cases/adapters/mysql2/bind_parameter_test.rb +5 -3
  24. data/test/cases/adapters/mysql2/boolean_test.rb +6 -4
  25. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +26 -24
  26. data/test/cases/adapters/mysql2/charset_collation_test.rb +20 -17
  27. data/test/cases/adapters/mysql2/connection_test.rb +48 -50
  28. data/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb +28 -0
  29. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +23 -19
  30. data/test/cases/adapters/mysql2/enum_test.rb +32 -11
  31. data/test/cases/adapters/mysql2/explain_test.rb +13 -11
  32. data/test/cases/adapters/mysql2/json_test.rb +17 -188
  33. data/test/cases/adapters/mysql2/mysql2_adapter_prevent_writes_test.rb +208 -0
  34. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +183 -28
  35. data/test/cases/adapters/mysql2/nested_deadlock_test.rb +75 -0
  36. data/test/cases/adapters/mysql2/optimizer_hints_test.rb +69 -0
  37. data/test/cases/adapters/mysql2/schema_migrations_test.rb +26 -21
  38. data/test/cases/adapters/mysql2/schema_test.rb +24 -22
  39. data/test/cases/adapters/mysql2/set_test.rb +32 -0
  40. data/test/cases/adapters/mysql2/sp_test.rb +10 -8
  41. data/test/cases/adapters/mysql2/sql_types_test.rb +8 -6
  42. data/test/cases/adapters/mysql2/table_options_test.rb +93 -10
  43. data/test/cases/adapters/mysql2/transaction_test.rb +151 -0
  44. data/test/cases/adapters/mysql2/unsigned_type_test.rb +11 -9
  45. data/test/cases/adapters/mysql2/virtual_column_test.rb +66 -0
  46. data/test/cases/adapters/postgresql/active_schema_test.rb +40 -25
  47. data/test/cases/adapters/postgresql/array_test.rb +118 -63
  48. data/test/cases/adapters/postgresql/bit_string_test.rb +12 -10
  49. data/test/cases/adapters/postgresql/bytea_test.rb +26 -25
  50. data/test/cases/adapters/postgresql/case_insensitive_test.rb +10 -9
  51. data/test/cases/adapters/postgresql/change_schema_test.rb +7 -5
  52. data/test/cases/adapters/postgresql/cidr_test.rb +2 -0
  53. data/test/cases/adapters/postgresql/citext_test.rb +58 -58
  54. data/test/cases/adapters/postgresql/collation_test.rb +17 -15
  55. data/test/cases/adapters/postgresql/composite_test.rb +25 -23
  56. data/test/cases/adapters/postgresql/connection_test.rb +73 -85
  57. data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +74 -0
  58. data/test/cases/adapters/postgresql/datatype_test.rb +19 -22
  59. data/test/cases/adapters/postgresql/date_test.rb +42 -0
  60. data/test/cases/adapters/postgresql/domain_test.rb +9 -7
  61. data/test/cases/adapters/postgresql/enum_test.rb +12 -10
  62. data/test/cases/adapters/postgresql/explain_test.rb +10 -8
  63. data/test/cases/adapters/postgresql/extension_migration_test.rb +13 -12
  64. data/test/cases/adapters/postgresql/foreign_table_test.rb +109 -0
  65. data/test/cases/adapters/postgresql/full_text_test.rb +8 -6
  66. data/test/cases/adapters/postgresql/geometric_test.rb +57 -63
  67. data/test/cases/adapters/postgresql/hstore_test.rb +288 -280
  68. data/test/cases/adapters/postgresql/infinity_test.rb +54 -15
  69. data/test/cases/adapters/postgresql/integer_test.rb +2 -0
  70. data/test/cases/adapters/postgresql/interval_test.rb +99 -0
  71. data/test/cases/adapters/postgresql/json_test.rb +16 -201
  72. data/test/cases/adapters/postgresql/ltree_test.rb +14 -16
  73. data/test/cases/adapters/postgresql/money_test.rb +47 -16
  74. data/test/cases/adapters/postgresql/network_test.rb +36 -28
  75. data/test/cases/adapters/postgresql/numbers_test.rb +7 -5
  76. data/test/cases/adapters/postgresql/optimizer_hints_test.rb +71 -0
  77. data/test/cases/adapters/postgresql/partitions_test.rb +22 -0
  78. data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +205 -0
  79. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +178 -136
  80. data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +27 -0
  81. data/test/cases/adapters/postgresql/quoting_test.rb +12 -6
  82. data/test/cases/adapters/postgresql/range_test.rb +406 -292
  83. data/test/cases/adapters/postgresql/referential_integrity_test.rb +16 -15
  84. data/test/cases/adapters/postgresql/rename_table_test.rb +9 -8
  85. data/test/cases/adapters/postgresql/schema_authorization_test.rb +14 -23
  86. data/test/cases/adapters/postgresql/schema_test.rb +207 -91
  87. data/test/cases/adapters/postgresql/serial_test.rb +9 -7
  88. data/test/cases/adapters/postgresql/statement_pool_test.rb +26 -6
  89. data/test/cases/adapters/postgresql/timestamp_test.rb +17 -15
  90. data/test/cases/adapters/postgresql/transaction_nested_test.rb +114 -0
  91. data/test/cases/adapters/postgresql/transaction_test.rb +189 -0
  92. data/test/cases/adapters/postgresql/type_lookup_test.rb +12 -10
  93. data/test/cases/adapters/postgresql/utils_test.rb +11 -9
  94. data/test/cases/adapters/postgresql/uuid_test.rb +226 -109
  95. data/test/cases/adapters/postgresql/xml_test.rb +10 -14
  96. data/test/cases/adapters/sqlite3/collation_test.rb +26 -15
  97. data/test/cases/adapters/sqlite3/copy_table_test.rb +31 -28
  98. data/test/cases/adapters/sqlite3/explain_test.rb +13 -11
  99. data/test/cases/adapters/sqlite3/json_test.rb +29 -0
  100. data/test/cases/adapters/sqlite3/quoting_test.rb +35 -57
  101. data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +186 -0
  102. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +318 -131
  103. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +11 -11
  104. data/test/cases/adapters/sqlite3/statement_pool_test.rb +7 -6
  105. data/test/cases/adapters/sqlite3/transaction_test.rb +123 -0
  106. data/test/cases/aggregations_test.rb +14 -12
  107. data/test/cases/annotate_test.rb +46 -0
  108. data/test/cases/ar_schema_test.rb +153 -86
  109. data/test/cases/arel/attributes/attribute_test.rb +1145 -0
  110. data/test/cases/arel/attributes/math_test.rb +83 -0
  111. data/test/cases/arel/attributes_test.rb +27 -0
  112. data/test/cases/arel/collectors/bind_test.rb +40 -0
  113. data/test/cases/arel/collectors/composite_test.rb +47 -0
  114. data/test/cases/arel/collectors/sql_string_test.rb +41 -0
  115. data/test/cases/arel/collectors/substitute_bind_collector_test.rb +48 -0
  116. data/test/cases/arel/crud_test.rb +65 -0
  117. data/test/cases/arel/delete_manager_test.rb +53 -0
  118. data/test/cases/arel/factory_methods_test.rb +46 -0
  119. data/test/cases/arel/helper.rb +45 -0
  120. data/test/cases/arel/insert_manager_test.rb +241 -0
  121. data/test/cases/arel/nodes/and_test.rb +30 -0
  122. data/test/cases/arel/nodes/as_test.rb +36 -0
  123. data/test/cases/arel/nodes/ascending_test.rb +46 -0
  124. data/test/cases/arel/nodes/bin_test.rb +35 -0
  125. data/test/cases/arel/nodes/binary_test.rb +29 -0
  126. data/test/cases/arel/nodes/bind_param_test.rb +22 -0
  127. data/test/cases/arel/nodes/case_test.rb +96 -0
  128. data/test/cases/arel/nodes/casted_test.rb +18 -0
  129. data/test/cases/arel/nodes/comment_test.rb +22 -0
  130. data/test/cases/arel/nodes/count_test.rb +35 -0
  131. data/test/cases/arel/nodes/delete_statement_test.rb +36 -0
  132. data/test/cases/arel/nodes/descending_test.rb +46 -0
  133. data/test/cases/arel/nodes/distinct_test.rb +21 -0
  134. data/test/cases/arel/nodes/equality_test.rb +62 -0
  135. data/test/cases/arel/nodes/extract_test.rb +43 -0
  136. data/test/cases/arel/nodes/false_test.rb +21 -0
  137. data/test/cases/arel/nodes/grouping_test.rb +26 -0
  138. data/test/cases/arel/nodes/infix_operation_test.rb +42 -0
  139. data/test/cases/arel/nodes/insert_statement_test.rb +44 -0
  140. data/test/cases/arel/nodes/named_function_test.rb +48 -0
  141. data/test/cases/arel/nodes/node_test.rb +22 -0
  142. data/test/cases/arel/nodes/not_test.rb +31 -0
  143. data/test/cases/arel/nodes/or_test.rb +36 -0
  144. data/test/cases/arel/nodes/over_test.rb +69 -0
  145. data/test/cases/arel/nodes/select_core_test.rb +79 -0
  146. data/test/cases/arel/nodes/select_statement_test.rb +51 -0
  147. data/test/cases/arel/nodes/sql_literal_test.rb +75 -0
  148. data/test/cases/arel/nodes/sum_test.rb +35 -0
  149. data/test/cases/arel/nodes/table_alias_test.rb +29 -0
  150. data/test/cases/arel/nodes/true_test.rb +21 -0
  151. data/test/cases/arel/nodes/unary_operation_test.rb +41 -0
  152. data/test/cases/arel/nodes/update_statement_test.rb +60 -0
  153. data/test/cases/arel/nodes/window_test.rb +81 -0
  154. data/test/cases/arel/nodes_test.rb +34 -0
  155. data/test/cases/arel/select_manager_test.rb +1238 -0
  156. data/test/cases/arel/support/fake_record.rb +135 -0
  157. data/test/cases/arel/table_test.rb +216 -0
  158. data/test/cases/arel/update_manager_test.rb +126 -0
  159. data/test/cases/arel/visitors/dispatch_contamination_test.rb +78 -0
  160. data/test/cases/arel/visitors/dot_test.rb +90 -0
  161. data/test/cases/arel/visitors/mysql_test.rb +157 -0
  162. data/test/cases/arel/visitors/postgres_test.rb +366 -0
  163. data/test/cases/arel/visitors/sqlite_test.rb +75 -0
  164. data/test/cases/arel/visitors/to_sql_test.rb +750 -0
  165. data/test/cases/associations/belongs_to_associations_test.rb +510 -158
  166. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +4 -2
  167. data/test/cases/associations/callbacks_test.rb +56 -38
  168. data/test/cases/associations/cascaded_eager_loading_test.rb +118 -61
  169. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +138 -18
  170. data/test/cases/associations/eager_load_nested_include_test.rb +38 -37
  171. data/test/cases/associations/eager_singularization_test.rb +21 -21
  172. data/test/cases/associations/eager_test.rb +559 -415
  173. data/test/cases/associations/extension_test.rb +18 -12
  174. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +234 -213
  175. data/test/cases/associations/has_many_associations_test.rb +1038 -465
  176. data/test/cases/associations/has_many_through_associations_test.rb +558 -249
  177. data/test/cases/associations/has_one_associations_test.rb +294 -129
  178. data/test/cases/associations/has_one_through_associations_test.rb +121 -75
  179. data/test/cases/associations/inner_join_association_test.rb +114 -38
  180. data/test/cases/associations/inverse_associations_test.rb +606 -398
  181. data/test/cases/associations/join_model_test.rb +158 -148
  182. data/test/cases/associations/left_outer_join_association_test.rb +59 -24
  183. data/test/cases/associations/nested_through_associations_test.rb +166 -109
  184. data/test/cases/associations/required_test.rb +35 -10
  185. data/test/cases/associations_test.rb +241 -110
  186. data/test/cases/attribute_methods/read_test.rb +11 -11
  187. data/test/cases/attribute_methods_test.rb +413 -298
  188. data/test/cases/attributes_test.rb +145 -27
  189. data/test/cases/autosave_association_test.rb +681 -436
  190. data/test/cases/base_prevent_writes_test.rb +229 -0
  191. data/test/cases/base_test.rb +599 -542
  192. data/test/cases/batches_test.rb +288 -82
  193. data/test/cases/binary_test.rb +26 -31
  194. data/test/cases/bind_parameter_test.rb +194 -21
  195. data/test/cases/boolean_test.rb +52 -0
  196. data/test/cases/cache_key_test.rb +110 -5
  197. data/test/cases/calculations_test.rb +740 -177
  198. data/test/cases/callbacks_test.rb +74 -207
  199. data/test/cases/clone_test.rb +15 -10
  200. data/test/cases/coders/json_test.rb +2 -0
  201. data/test/cases/coders/yaml_column_test.rb +16 -13
  202. data/test/cases/collection_cache_key_test.rb +177 -20
  203. data/test/cases/column_alias_test.rb +9 -7
  204. data/test/cases/column_definition_test.rb +10 -68
  205. data/test/cases/comment_test.rb +166 -107
  206. data/test/cases/connection_adapters/adapter_leasing_test.rb +14 -10
  207. data/test/cases/connection_adapters/connection_handler_test.rb +358 -51
  208. data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +400 -0
  209. data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +103 -0
  210. data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +499 -0
  211. data/test/cases/connection_adapters/connection_swapping_nested_test.rb +457 -0
  212. data/test/cases/connection_adapters/legacy_connection_handlers_multi_db_test.rb +486 -0
  213. data/test/cases/connection_adapters/legacy_connection_handlers_sharding_db_test.rb +586 -0
  214. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +319 -138
  215. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +62 -50
  216. data/test/cases/connection_adapters/schema_cache_test.rb +259 -26
  217. data/test/cases/connection_adapters/type_lookup_test.rb +96 -95
  218. data/test/cases/connection_management_test.rb +13 -11
  219. data/test/cases/connection_pool_test.rb +316 -83
  220. data/test/cases/core_test.rb +82 -58
  221. data/test/cases/counter_cache_test.rb +204 -50
  222. data/test/cases/custom_locking_test.rb +5 -3
  223. data/test/cases/database_configurations/hash_config_test.rb +74 -0
  224. data/test/cases/database_configurations/resolver_test.rb +150 -0
  225. data/test/cases/database_configurations_test.rb +145 -0
  226. data/test/cases/database_selector_test.rb +296 -0
  227. data/test/cases/database_statements_test.rb +18 -16
  228. data/test/cases/date_test.rb +8 -16
  229. data/test/cases/date_time_precision_test.rb +100 -78
  230. data/test/cases/date_time_test.rb +23 -8
  231. data/test/cases/defaults_test.rb +106 -71
  232. data/test/cases/delegated_type_test.rb +57 -0
  233. data/test/cases/dirty_test.rb +419 -223
  234. data/test/cases/disconnected_test.rb +6 -6
  235. data/test/cases/dup_test.rb +54 -27
  236. data/test/cases/enum_test.rb +461 -82
  237. data/test/cases/errors_test.rb +7 -7
  238. data/test/cases/explain_subscriber_test.rb +17 -15
  239. data/test/cases/explain_test.rb +11 -19
  240. data/test/cases/filter_attributes_test.rb +153 -0
  241. data/test/cases/finder_respond_to_test.rb +14 -14
  242. data/test/cases/finder_test.rb +669 -287
  243. data/test/cases/fixture_set/file_test.rb +34 -38
  244. data/test/cases/fixtures_test.rb +833 -176
  245. data/test/cases/forbidden_attributes_protection_test.rb +32 -67
  246. data/test/cases/habtm_destroy_order_test.rb +25 -25
  247. data/test/cases/helper.rb +78 -49
  248. data/test/cases/hot_compatibility_test.rb +33 -32
  249. data/test/cases/i18n_test.rb +18 -17
  250. data/test/cases/inheritance_test.rb +180 -115
  251. data/test/cases/insert_all_test.rb +489 -0
  252. data/test/cases/instrumentation_test.rb +101 -0
  253. data/test/cases/integration_test.rb +119 -31
  254. data/test/cases/invalid_connection_test.rb +18 -16
  255. data/test/cases/invertible_migration_test.rb +183 -43
  256. data/test/cases/json_attribute_test.rb +35 -0
  257. data/test/cases/json_serialization_test.rb +57 -58
  258. data/test/cases/json_shared_test_cases.rb +290 -0
  259. data/test/cases/locking_test.rb +413 -119
  260. data/test/cases/log_subscriber_test.rb +68 -26
  261. data/test/cases/marshal_serialization_test.rb +39 -0
  262. data/test/cases/migration/change_schema_test.rb +118 -72
  263. data/test/cases/migration/change_table_test.rb +138 -30
  264. data/test/cases/migration/check_constraint_test.rb +162 -0
  265. data/test/cases/migration/column_attributes_test.rb +45 -35
  266. data/test/cases/migration/column_positioning_test.rb +18 -6
  267. data/test/cases/migration/columns_test.rb +93 -77
  268. data/test/cases/migration/command_recorder_test.rb +121 -34
  269. data/test/cases/migration/compatibility_test.rb +578 -23
  270. data/test/cases/migration/create_join_table_test.rb +35 -25
  271. data/test/cases/migration/foreign_key_test.rb +503 -284
  272. data/test/cases/migration/helper.rb +4 -3
  273. data/test/cases/migration/index_test.rb +119 -70
  274. data/test/cases/migration/logger_test.rb +9 -6
  275. data/test/cases/migration/pending_migrations_test.rb +88 -34
  276. data/test/cases/migration/references_foreign_key_test.rb +164 -150
  277. data/test/cases/migration/references_index_test.rb +38 -19
  278. data/test/cases/migration/references_statements_test.rb +15 -14
  279. data/test/cases/migration/rename_table_test.rb +53 -30
  280. data/test/cases/migration_test.rb +637 -269
  281. data/test/cases/migrator_test.rb +191 -135
  282. data/test/cases/mixin_test.rb +7 -11
  283. data/test/cases/modules_test.rb +36 -34
  284. data/test/cases/multi_db_migrator_test.rb +223 -0
  285. data/test/cases/multiparameter_attributes_test.rb +60 -33
  286. data/test/cases/multiple_db_test.rb +16 -22
  287. data/test/cases/nested_attributes_test.rb +341 -320
  288. data/test/cases/nested_attributes_with_callbacks_test.rb +26 -24
  289. data/test/cases/null_relation_test.rb +84 -0
  290. data/test/cases/numeric_data_test.rb +93 -0
  291. data/test/cases/persistence_test.rb +361 -269
  292. data/test/cases/pooled_connections_test.rb +18 -26
  293. data/test/cases/prepared_statement_status_test.rb +48 -0
  294. data/test/cases/primary_keys_test.rb +210 -104
  295. data/test/cases/query_cache_test.rb +610 -141
  296. data/test/cases/quoting_test.rb +132 -31
  297. data/test/cases/readonly_test.rb +49 -48
  298. data/test/cases/reaper_test.rb +146 -32
  299. data/test/cases/reflection_test.rb +167 -156
  300. data/test/cases/relation/delegation_test.rb +49 -36
  301. data/test/cases/relation/delete_all_test.rb +117 -0
  302. data/test/cases/relation/merging_test.rb +319 -42
  303. data/test/cases/relation/mutation_test.rb +55 -93
  304. data/test/cases/relation/or_test.rb +129 -29
  305. data/test/cases/relation/predicate_builder_test.rb +21 -6
  306. data/test/cases/relation/record_fetch_warning_test.rb +5 -3
  307. data/test/cases/relation/select_test.rb +67 -0
  308. data/test/cases/relation/update_all_test.rb +317 -0
  309. data/test/cases/relation/where_chain_test.rb +68 -32
  310. data/test/cases/relation/where_clause_test.rb +136 -61
  311. data/test/cases/relation/where_test.rb +155 -48
  312. data/test/cases/relation_test.rb +266 -112
  313. data/test/cases/relations_test.rb +969 -744
  314. data/test/cases/reload_models_test.rb +13 -9
  315. data/test/cases/reserved_word_test.rb +141 -0
  316. data/test/cases/result_test.rb +68 -17
  317. data/test/cases/sanitize_test.rb +87 -71
  318. data/test/cases/schema_dumper_test.rb +221 -128
  319. data/test/cases/schema_loading_test.rb +3 -2
  320. data/test/cases/scoping/default_scoping_test.rb +185 -144
  321. data/test/cases/scoping/named_scoping_test.rb +177 -89
  322. data/test/cases/scoping/relation_scoping_test.rb +197 -75
  323. data/test/cases/secure_token_test.rb +18 -3
  324. data/test/cases/serialization_test.rb +30 -28
  325. data/test/cases/serialized_attribute_test.rb +133 -42
  326. data/test/cases/signed_id_test.rb +168 -0
  327. data/test/cases/statement_cache_test.rb +41 -24
  328. data/test/cases/statement_invalid_test.rb +42 -0
  329. data/test/cases/store_test.rb +180 -55
  330. data/test/cases/strict_loading_test.rb +473 -0
  331. data/test/cases/suppressor_test.rb +26 -12
  332. data/test/cases/tasks/database_tasks_test.rb +1258 -194
  333. data/test/cases/tasks/mysql_rake_test.rb +370 -298
  334. data/test/cases/tasks/postgresql_rake_test.rb +481 -251
  335. data/test/cases/tasks/sqlite_rake_test.rb +225 -178
  336. data/test/cases/test_case.rb +51 -40
  337. data/test/cases/test_databases_test.rb +79 -0
  338. data/test/cases/test_fixtures_test.rb +79 -19
  339. data/test/cases/time_precision_test.rb +98 -76
  340. data/test/cases/timestamp_test.rb +102 -99
  341. data/test/cases/touch_later_test.rb +12 -10
  342. data/test/cases/transaction_callbacks_test.rb +344 -90
  343. data/test/cases/transaction_isolation_test.rb +12 -12
  344. data/test/cases/transactions_test.rb +612 -162
  345. data/test/cases/type/adapter_specific_registry_test.rb +14 -2
  346. data/test/cases/type/date_time_test.rb +4 -2
  347. data/test/cases/type/integer_test.rb +4 -2
  348. data/test/cases/type/string_test.rb +10 -8
  349. data/test/cases/type/time_test.rb +28 -0
  350. data/test/cases/type/type_map_test.rb +29 -28
  351. data/test/cases/type/unsigned_integer_test.rb +19 -0
  352. data/test/cases/type_test.rb +2 -0
  353. data/test/cases/types_test.rb +3 -1
  354. data/test/cases/unconnected_test.rb +14 -1
  355. data/test/cases/unsafe_raw_sql_test.rb +274 -0
  356. data/test/cases/validations/absence_validation_test.rb +19 -17
  357. data/test/cases/validations/association_validation_test.rb +30 -28
  358. data/test/cases/validations/i18n_generate_message_validation_test.rb +34 -16
  359. data/test/cases/validations/i18n_validation_test.rb +22 -21
  360. data/test/cases/validations/length_validation_test.rb +34 -33
  361. data/test/cases/validations/numericality_validation_test.rb +181 -0
  362. data/test/cases/validations/presence_validation_test.rb +21 -19
  363. data/test/cases/validations/uniqueness_validation_test.rb +156 -86
  364. data/test/cases/validations_repair_helper.rb +2 -0
  365. data/test/cases/validations_test.rb +61 -26
  366. data/test/cases/view_test.rb +122 -116
  367. data/test/cases/yaml_serialization_test.rb +79 -34
  368. data/test/config.example.yml +19 -19
  369. data/test/config.rb +3 -1
  370. data/test/config.yml +16 -6
  371. data/test/fixtures/all/namespaced/accounts.yml +2 -0
  372. data/test/fixtures/author_addresses.yml +1 -8
  373. data/test/fixtures/authors.yml +1 -7
  374. data/test/fixtures/binaries.yml +4 -0
  375. data/test/fixtures/books.yml +9 -2
  376. data/test/fixtures/categories_posts.yml +3 -0
  377. data/test/fixtures/citations.yml +5 -0
  378. data/test/fixtures/comments.yml +7 -0
  379. data/test/fixtures/companies.yml +5 -0
  380. data/test/fixtures/computers.yml +2 -0
  381. data/test/fixtures/customers.yml +10 -1
  382. data/test/fixtures/developers.yml +1 -1
  383. data/test/fixtures/essays.yml +10 -0
  384. data/test/fixtures/faces.yml +3 -3
  385. data/test/fixtures/humans.yml +5 -0
  386. data/test/fixtures/interests.yml +7 -7
  387. data/test/fixtures/memberships.yml +7 -0
  388. data/test/fixtures/minimalistics.yml +3 -0
  389. data/test/fixtures/mixed_case_monkeys.yml +2 -2
  390. data/test/fixtures/naked/yml/courses_with_invalid_key.yml +3 -0
  391. data/test/fixtures/naked/yml/parrots.yml +1 -0
  392. data/test/fixtures/other_books.yml +26 -0
  393. data/test/fixtures/other_posts.yml +1 -0
  394. data/test/fixtures/parrots.yml +7 -1
  395. data/test/fixtures/pirates.yml +3 -0
  396. data/test/fixtures/posts.yml +11 -3
  397. data/test/fixtures/readers.yml +6 -0
  398. data/test/fixtures/reserved_words/values.yml +2 -2
  399. data/test/fixtures/sponsors.yml +3 -0
  400. data/test/fixtures/strict_zines.yml +2 -0
  401. data/test/fixtures/subscribers.yml +1 -1
  402. data/test/fixtures/tasks.yml +1 -1
  403. data/test/fixtures/warehouse-things.yml +3 -0
  404. data/test/migrations/10_urban/9_add_expressions.rb +2 -0
  405. data/test/migrations/decimal/1_give_me_big_numbers.rb +6 -4
  406. data/test/migrations/magic/1_currencies_have_symbols.rb +3 -2
  407. data/test/migrations/missing/1000_people_have_middle_names.rb +2 -0
  408. data/test/migrations/missing/1_people_have_last_names.rb +2 -0
  409. data/test/migrations/missing/3_we_need_reminders.rb +2 -0
  410. data/test/migrations/missing/4_innocent_jointable.rb +3 -1
  411. data/test/migrations/rename/1_we_need_things.rb +2 -0
  412. data/test/migrations/rename/2_rename_things.rb +2 -0
  413. data/test/migrations/to_copy/1_people_have_hobbies.rb +3 -1
  414. data/test/migrations/to_copy/2_people_have_descriptions.rb +3 -1
  415. data/test/migrations/to_copy2/1_create_articles.rb +2 -0
  416. data/test/migrations/to_copy2/2_create_comments.rb +3 -1
  417. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +3 -1
  418. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +3 -1
  419. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +3 -1
  420. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +2 -0
  421. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +2 -0
  422. data/test/migrations/valid/1_valid_people_have_last_names.rb +2 -0
  423. data/test/migrations/valid/2_we_need_reminders.rb +2 -0
  424. data/test/migrations/valid/3_innocent_jointable.rb +3 -1
  425. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +2 -0
  426. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +2 -0
  427. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +3 -1
  428. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +2 -0
  429. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +2 -0
  430. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +3 -1
  431. data/test/migrations/version_check/20131219224947_migration_version_check.rb +2 -0
  432. data/test/models/account.rb +46 -0
  433. data/test/models/admin/account.rb +3 -1
  434. data/test/models/admin/randomly_named_c1.rb +2 -0
  435. data/test/models/admin/user.rb +16 -8
  436. data/test/models/admin.rb +4 -2
  437. data/test/models/aircraft.rb +3 -1
  438. data/test/models/arunit2_model.rb +2 -0
  439. data/test/models/author.rb +153 -102
  440. data/test/models/auto_id.rb +2 -0
  441. data/test/models/autoloadable/extra_firm.rb +2 -0
  442. data/test/models/binary.rb +3 -1
  443. data/test/models/binary_field.rb +6 -0
  444. data/test/models/bird.rb +13 -1
  445. data/test/models/book.rb +14 -4
  446. data/test/models/book_destroy_async.rb +24 -0
  447. data/test/models/boolean.rb +5 -0
  448. data/test/models/bulb.rb +13 -4
  449. data/test/models/cake_designer.rb +2 -0
  450. data/test/models/car.rb +17 -10
  451. data/test/models/carrier.rb +2 -0
  452. data/test/models/cart.rb +5 -0
  453. data/test/models/cat.rb +2 -0
  454. data/test/models/categorization.rb +8 -6
  455. data/test/models/category.rb +28 -16
  456. data/test/models/chef.rb +2 -0
  457. data/test/models/citation.rb +5 -1
  458. data/test/models/club.rb +13 -10
  459. data/test/models/college.rb +4 -2
  460. data/test/models/column.rb +2 -0
  461. data/test/models/column_name.rb +2 -0
  462. data/test/models/comment.rb +32 -10
  463. data/test/models/company.rb +102 -106
  464. data/test/models/company_in_module.rb +27 -26
  465. data/test/models/computer.rb +3 -1
  466. data/test/models/contact.rb +15 -13
  467. data/test/models/content.rb +5 -3
  468. data/test/models/contract.rb +21 -3
  469. data/test/models/country.rb +2 -4
  470. data/test/models/course.rb +3 -1
  471. data/test/models/customer.rb +10 -8
  472. data/test/models/customer_carrier.rb +2 -0
  473. data/test/models/dashboard.rb +2 -0
  474. data/test/models/default.rb +2 -0
  475. data/test/models/department.rb +2 -0
  476. data/test/models/destroy_async_parent.rb +15 -0
  477. data/test/models/destroy_async_parent_soft_delete.rb +20 -0
  478. data/test/models/developer.rb +152 -85
  479. data/test/models/dl_keyed_belongs_to.rb +13 -0
  480. data/test/models/dl_keyed_belongs_to_soft_delete.rb +19 -0
  481. data/test/models/dl_keyed_has_many.rb +5 -0
  482. data/test/models/dl_keyed_has_many_through.rb +5 -0
  483. data/test/models/dl_keyed_has_one.rb +5 -0
  484. data/test/models/dl_keyed_join.rb +10 -0
  485. data/test/models/dog.rb +2 -0
  486. data/test/models/dog_lover.rb +2 -0
  487. data/test/models/doubloon.rb +3 -1
  488. data/test/models/drink_designer.rb +17 -0
  489. data/test/models/edge.rb +4 -2
  490. data/test/models/electron.rb +2 -0
  491. data/test/models/engine.rb +3 -2
  492. data/test/models/entrant.rb +2 -0
  493. data/test/models/entry.rb +5 -0
  494. data/test/models/essay.rb +6 -3
  495. data/test/models/essay_destroy_async.rb +12 -0
  496. data/test/models/event.rb +3 -1
  497. data/test/models/eye.rb +5 -3
  498. data/test/models/face.rb +14 -6
  499. data/test/models/family.rb +6 -0
  500. data/test/models/family_tree.rb +6 -0
  501. data/test/models/friendship.rb +5 -3
  502. data/test/models/frog.rb +8 -0
  503. data/test/models/guid.rb +3 -1
  504. data/test/models/guitar.rb +2 -0
  505. data/test/models/hotel.rb +5 -3
  506. data/test/models/human.rb +39 -0
  507. data/test/models/image.rb +3 -1
  508. data/test/models/interest.rb +14 -3
  509. data/test/models/invoice.rb +4 -2
  510. data/test/models/item.rb +3 -1
  511. data/test/models/job.rb +5 -3
  512. data/test/models/joke.rb +4 -2
  513. data/test/models/keyboard.rb +3 -1
  514. data/test/models/legacy_thing.rb +2 -0
  515. data/test/models/lesson.rb +2 -0
  516. data/test/models/line_item.rb +3 -1
  517. data/test/models/liquid.rb +2 -0
  518. data/test/models/matey.rb +3 -1
  519. data/test/models/measurement.rb +4 -0
  520. data/test/models/member.rb +23 -20
  521. data/test/models/member_detail.rb +3 -0
  522. data/test/models/member_type.rb +2 -0
  523. data/test/models/membership.rb +4 -1
  524. data/test/models/mentor.rb +3 -1
  525. data/test/models/message.rb +5 -0
  526. data/test/models/minimalistic.rb +2 -0
  527. data/test/models/minivan.rb +3 -2
  528. data/test/models/mixed_case_monkey.rb +3 -1
  529. data/test/models/molecule.rb +2 -0
  530. data/test/models/mouse.rb +6 -0
  531. data/test/models/movie.rb +2 -0
  532. data/test/models/node.rb +4 -2
  533. data/test/models/non_primary_key.rb +2 -0
  534. data/test/models/notification.rb +2 -0
  535. data/test/models/numeric_data.rb +12 -0
  536. data/test/models/order.rb +4 -2
  537. data/test/models/organization.rb +9 -7
  538. data/test/models/other_dog.rb +3 -1
  539. data/test/models/owner.rb +6 -4
  540. data/test/models/parrot.rb +12 -4
  541. data/test/models/person.rb +59 -54
  542. data/test/models/personal_legacy_thing.rb +3 -1
  543. data/test/models/pet.rb +4 -2
  544. data/test/models/pet_treasure.rb +2 -0
  545. data/test/models/pirate.rb +67 -43
  546. data/test/models/possession.rb +3 -1
  547. data/test/models/post.rb +184 -86
  548. data/test/models/price_estimate.rb +11 -1
  549. data/test/models/professor.rb +3 -1
  550. data/test/models/project.rb +14 -12
  551. data/test/models/publisher/article.rb +2 -0
  552. data/test/models/publisher/magazine.rb +2 -0
  553. data/test/models/publisher.rb +2 -0
  554. data/test/models/randomly_named_c1.rb +2 -0
  555. data/test/models/rating.rb +5 -1
  556. data/test/models/reader.rb +7 -5
  557. data/test/models/recipe.rb +2 -0
  558. data/test/models/record.rb +2 -0
  559. data/test/models/reference.rb +6 -3
  560. data/test/models/reply.rb +39 -21
  561. data/test/models/room.rb +6 -0
  562. data/test/models/section.rb +6 -0
  563. data/test/models/seminar.rb +6 -0
  564. data/test/models/session.rb +6 -0
  565. data/test/models/ship.rb +12 -9
  566. data/test/models/ship_part.rb +5 -3
  567. data/test/models/shop.rb +4 -2
  568. data/test/models/shop_account.rb +2 -0
  569. data/test/models/speedometer.rb +2 -0
  570. data/test/models/sponsor.rb +8 -5
  571. data/test/models/squeak.rb +6 -0
  572. data/test/models/strict_zine.rb +7 -0
  573. data/test/models/string_key_object.rb +2 -0
  574. data/test/models/student.rb +2 -0
  575. data/test/models/subscriber.rb +4 -2
  576. data/test/models/subscription.rb +5 -1
  577. data/test/models/tag.rb +6 -3
  578. data/test/models/tagging.rb +13 -6
  579. data/test/models/task.rb +2 -0
  580. data/test/models/topic.rb +54 -19
  581. data/test/models/toy.rb +4 -0
  582. data/test/models/traffic_light.rb +2 -0
  583. data/test/models/treasure.rb +5 -3
  584. data/test/models/treaty.rb +2 -4
  585. data/test/models/tree.rb +2 -0
  586. data/test/models/tuning_peg.rb +2 -0
  587. data/test/models/tyre.rb +2 -0
  588. data/test/models/user.rb +12 -4
  589. data/test/models/uuid_child.rb +2 -0
  590. data/test/models/uuid_item.rb +2 -0
  591. data/test/models/uuid_parent.rb +2 -0
  592. data/test/models/vegetables.rb +12 -3
  593. data/test/models/vertex.rb +6 -4
  594. data/test/models/warehouse_thing.rb +2 -0
  595. data/test/models/wheel.rb +3 -1
  596. data/test/models/without_table.rb +3 -1
  597. data/test/models/zine.rb +3 -1
  598. data/test/schema/mysql2_specific_schema.rb +49 -35
  599. data/test/schema/oracle_specific_schema.rb +13 -15
  600. data/test/schema/postgresql_specific_schema.rb +51 -40
  601. data/test/schema/schema.rb +334 -154
  602. data/test/schema/sqlite_specific_schema.rb +9 -16
  603. data/test/support/config.rb +26 -26
  604. data/test/support/connection.rb +14 -8
  605. data/test/support/connection_helper.rb +3 -1
  606. data/test/support/ddl_helper.rb +2 -0
  607. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic.dump +0 -0
  608. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic_associations.dump +0 -0
  609. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic.dump +0 -0
  610. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic_associations.dump +0 -0
  611. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic.dump +0 -0
  612. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic_associations.dump +0 -0
  613. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic.dump +0 -0
  614. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic_associations.dump +0 -0
  615. data/test/support/marshal_compatibility_fixtures/legacy_6_0_record_mysql.dump +0 -0
  616. data/test/support/marshal_compatibility_fixtures/legacy_relation.dump +0 -0
  617. data/test/support/schema_dumping_helper.rb +2 -0
  618. data/test/support/stubs/strong_parameters.rb +40 -0
  619. data/test/support/yaml_compatibility_fixtures/rails_v1_mysql.yml +206 -0
  620. data/test/support/yaml_compatibility_fixtures/rails_v2.yml +55 -0
  621. metadata +190 -14
@@ -1,48 +1,58 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cases/helper"
2
- require 'models/developer'
3
- require 'models/computer'
4
- require 'models/project'
5
- require 'models/company'
6
- require 'models/ship'
7
- require 'models/pirate'
8
- require 'models/car'
9
- require 'models/bulb'
10
- require 'models/author'
11
- require 'models/image'
12
- require 'models/post'
4
+ require "models/developer"
5
+ require "models/computer"
6
+ require "models/project"
7
+ require "models/company"
8
+ require "models/ship"
9
+ require "models/pirate"
10
+ require "models/car"
11
+ require "models/bulb"
12
+ require "models/author"
13
+ require "models/image"
14
+ require "models/post"
15
+ require "models/drink_designer"
16
+ require "models/chef"
17
+ require "models/department"
18
+ require "models/club"
19
+ require "models/membership"
13
20
 
14
21
  class HasOneAssociationsTest < ActiveRecord::TestCase
15
22
  self.use_transactional_tests = false unless supports_savepoints?
16
- fixtures :accounts, :companies, :developers, :projects, :developers_projects, :ships, :pirates
23
+ fixtures :accounts, :companies, :developers, :projects, :developers_projects,
24
+ :ships, :pirates, :authors, :author_addresses, :books, :memberships, :clubs
17
25
 
18
26
  def setup
19
27
  Account.destroyed_account_ids.clear
20
28
  end
21
29
 
22
30
  def test_has_one
23
- assert_equal companies(:first_firm).account, Account.find(1)
24
- assert_equal Account.find(1).credit_limit, companies(:first_firm).account.credit_limit
31
+ firm = companies(:first_firm)
32
+ first_account = Account.find(1)
33
+ assert_sql(/LIMIT|ROWNUM <=|FETCH FIRST/) do
34
+ assert_equal first_account, firm.account
35
+ assert_equal first_account.credit_limit, firm.account.credit_limit
36
+ end
25
37
  end
26
38
 
27
39
  def test_has_one_does_not_use_order_by
28
- ActiveRecord::SQLCounter.clear_log
29
- companies(:first_firm).account
30
- ensure
31
- assert ActiveRecord::SQLCounter.log_all.all? { |sql| /order by/i !~ sql }, 'ORDER BY was used in the query'
40
+ sql_log = capture_sql { companies(:first_firm).account }
41
+ assert sql_log.all? { |sql| !/order by/i.match?(sql) }, "ORDER BY was used in the query: #{sql_log}"
32
42
  end
33
43
 
34
44
  def test_has_one_cache_nils
35
45
  firm = companies(:another_firm)
36
46
  assert_queries(1) { assert_nil firm.account }
37
- assert_queries(0) { assert_nil firm.account }
47
+ assert_no_queries { assert_nil firm.account }
38
48
 
39
- firms = Firm.all.merge!(:includes => :account).to_a
40
- assert_queries(0) { firms.each(&:account) }
49
+ firms = Firm.includes(:account).to_a
50
+ assert_no_queries { firms.each(&:account) }
41
51
  end
42
52
 
43
53
  def test_with_select
44
54
  assert_equal Firm.find(1).account_with_select.attributes.size, 2
45
- assert_equal Firm.all.merge!(:includes => :account_with_select).find(1).account_with_select.attributes.size, 2
55
+ assert_equal Firm.all.merge!(includes: :account_with_select).find(1).account_with_select.attributes.size, 2
46
56
  end
47
57
 
48
58
  def test_finding_using_primary_key
@@ -102,17 +112,32 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
102
112
  def test_nullification_on_association_change
103
113
  firm = companies(:rails_core)
104
114
  old_account_id = firm.account.id
105
- firm.account = Account.new(:credit_limit => 5)
115
+ firm.account = Account.new(credit_limit: 5)
106
116
  # account is dependent with nullify, therefore its firm_id should be nil
107
117
  assert_nil Account.find(old_account_id).firm_id
108
118
  end
109
119
 
120
+ def test_nullify_on_polymorphic_association
121
+ department = Department.create!
122
+ designer = DrinkDesignerWithPolymorphicDependentNullifyChef.create!
123
+ chef = department.chefs.create!(employable: designer)
124
+
125
+ assert_equal chef.employable_id, designer.id
126
+ assert_equal chef.employable_type, designer.class.name
127
+
128
+ designer.destroy!
129
+ chef.reload
130
+
131
+ assert_nil chef.employable_id
132
+ assert_nil chef.employable_type
133
+ end
134
+
110
135
  def test_nullification_on_destroyed_association
111
136
  developer = Developer.create!(name: "Someone")
112
137
  ship = Ship.create!(name: "Planet Caravan", developer: developer)
113
138
  ship.destroy
114
- assert !ship.persisted?
115
- assert !developer.persisted?
139
+ assert_not_predicate ship, :persisted?
140
+ assert_not_predicate developer, :persisted?
116
141
  end
117
142
 
118
143
  def test_natural_assignment_to_nil_after_destroy
@@ -125,12 +150,12 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
125
150
  end
126
151
 
127
152
  def test_association_change_calls_delete
128
- companies(:first_firm).deletable_account = Account.new(:credit_limit => 5)
153
+ companies(:first_firm).deletable_account = Account.new(credit_limit: 5)
129
154
  assert_equal [], Account.destroyed_account_ids[companies(:first_firm).id]
130
155
  end
131
156
 
132
157
  def test_association_change_calls_destroy
133
- companies(:first_firm).account = Account.new(:credit_limit => 5)
158
+ companies(:first_firm).account = Account.new(credit_limit: 5)
134
159
  assert_equal [companies(:first_firm).id], Account.destroyed_account_ids[companies(:first_firm).id]
135
160
  end
136
161
 
@@ -170,69 +195,50 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
170
195
  end
171
196
 
172
197
  def test_dependence_with_nil_associate
173
- firm = DependentFirm.new(:name => 'nullify')
198
+ firm = DependentFirm.new(name: "nullify")
174
199
  firm.save!
175
200
  assert_nothing_raised { firm.destroy }
176
201
  end
177
202
 
178
203
  def test_restrict_with_exception
179
- firm = RestrictedWithExceptionFirm.create!(:name => 'restrict')
180
- firm.create_account(:credit_limit => 10)
181
-
182
- assert_not_nil firm.account
183
-
184
- assert_raise(ActiveRecord::DeleteRestrictionError) { firm.destroy }
185
- assert RestrictedWithExceptionFirm.exists?(:name => 'restrict')
186
- assert firm.account.present?
187
- end
188
-
189
- def test_restrict_with_error_is_deprecated_using_key_one
190
- I18n.backend = I18n::Backend::Simple.new
191
- I18n.backend.store_translations :en, activerecord: { errors: { messages: { restrict_dependent_destroy: { one: 'message for deprecated key' } } } }
192
-
193
- firm = RestrictedWithErrorFirm.create!(name: 'restrict')
204
+ firm = RestrictedWithExceptionFirm.create!(name: "restrict")
194
205
  firm.create_account(credit_limit: 10)
195
206
 
196
207
  assert_not_nil firm.account
197
208
 
198
- assert_deprecated { firm.destroy }
199
-
200
- assert !firm.errors.empty?
201
- assert_equal 'message for deprecated key', firm.errors[:base].first
202
- assert RestrictedWithErrorFirm.exists?(name: 'restrict')
203
- assert firm.account.present?
204
- ensure
205
- I18n.backend.reload!
209
+ assert_raise(ActiveRecord::DeleteRestrictionError) { firm.destroy }
210
+ assert RestrictedWithExceptionFirm.exists?(name: "restrict")
211
+ assert_predicate firm.account, :present?
206
212
  end
207
213
 
208
214
  def test_restrict_with_error
209
- firm = RestrictedWithErrorFirm.create!(:name => 'restrict')
210
- firm.create_account(:credit_limit => 10)
215
+ firm = RestrictedWithErrorFirm.create!(name: "restrict")
216
+ firm.create_account(credit_limit: 10)
211
217
 
212
218
  assert_not_nil firm.account
213
219
 
214
220
  firm.destroy
215
221
 
216
- assert !firm.errors.empty?
222
+ assert_not_empty firm.errors
217
223
  assert_equal "Cannot delete record because a dependent account exists", firm.errors[:base].first
218
- assert RestrictedWithErrorFirm.exists?(:name => 'restrict')
219
- assert firm.account.present?
224
+ assert RestrictedWithErrorFirm.exists?(name: "restrict")
225
+ assert_predicate firm.account, :present?
220
226
  end
221
227
 
222
228
  def test_restrict_with_error_with_locale
223
229
  I18n.backend = I18n::Backend::Simple.new
224
- I18n.backend.store_translations 'en', activerecord: {attributes: {restricted_with_error_firm: {account: 'firm account'}}}
225
- firm = RestrictedWithErrorFirm.create!(name: 'restrict')
230
+ I18n.backend.store_translations "en", activerecord: { attributes: { restricted_with_error_firm: { account: "firm account" } } }
231
+ firm = RestrictedWithErrorFirm.create!(name: "restrict")
226
232
  firm.create_account(credit_limit: 10)
227
233
 
228
234
  assert_not_nil firm.account
229
235
 
230
236
  firm.destroy
231
237
 
232
- assert !firm.errors.empty?
238
+ assert_not_empty firm.errors
233
239
  assert_equal "Cannot delete record because a dependent firm account exists", firm.errors[:base].first
234
- assert RestrictedWithErrorFirm.exists?(name: 'restrict')
235
- assert firm.account.present?
240
+ assert RestrictedWithErrorFirm.exists?(name: "restrict")
241
+ assert_predicate firm.account, :present?
236
242
  ensure
237
243
  I18n.backend.reload!
238
244
  end
@@ -247,9 +253,10 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
247
253
  end
248
254
 
249
255
  def test_build_association_dont_create_transaction
250
- assert_no_queries(ignore_none: false) {
251
- Firm.new.build_account
252
- }
256
+ firm = Firm.new
257
+ assert_queries(0) do
258
+ firm.build_account
259
+ end
253
260
  end
254
261
 
255
262
  def test_building_the_associated_object_with_implicit_sti_base_class
@@ -260,24 +267,24 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
260
267
 
261
268
  def test_building_the_associated_object_with_explicit_sti_base_class
262
269
  firm = DependentFirm.new
263
- company = firm.build_company(:type => "Company")
270
+ company = firm.build_company(type: "Company")
264
271
  assert_kind_of Company, company, "Expected #{company.class} to be a Company"
265
272
  end
266
273
 
267
274
  def test_building_the_associated_object_with_sti_subclass
268
275
  firm = DependentFirm.new
269
- company = firm.build_company(:type => "Client")
276
+ company = firm.build_company(type: "Client")
270
277
  assert_kind_of Client, company, "Expected #{company.class} to be a Client"
271
278
  end
272
279
 
273
280
  def test_building_the_associated_object_with_an_invalid_type
274
281
  firm = DependentFirm.new
275
- assert_raise(ActiveRecord::SubclassNotFound) { firm.build_company(:type => "Invalid") }
282
+ assert_raise(ActiveRecord::SubclassNotFound) { firm.build_company(type: "Invalid") }
276
283
  end
277
284
 
278
285
  def test_building_the_associated_object_with_an_unrelated_type
279
286
  firm = DependentFirm.new
280
- assert_raise(ActiveRecord::SubclassNotFound) { firm.build_company(:type => "Account") }
287
+ assert_raise(ActiveRecord::SubclassNotFound) { firm.build_company(type: "Account") }
281
288
  end
282
289
 
283
290
  def test_build_and_create_should_not_happen_within_scope
@@ -295,19 +302,19 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
295
302
  end
296
303
 
297
304
  def test_create_association
298
- firm = Firm.create(:name => "GlobalMegaCorp")
299
- account = firm.create_account(:credit_limit => 1000)
305
+ firm = Firm.create(name: "GlobalMegaCorp")
306
+ account = firm.create_account(credit_limit: 1000)
300
307
  assert_equal account, firm.reload.account
301
308
  end
302
309
 
303
310
  def test_create_association_with_bang
304
- firm = Firm.create(:name => "GlobalMegaCorp")
305
- account = firm.create_account!(:credit_limit => 1000)
311
+ firm = Firm.create(name: "GlobalMegaCorp")
312
+ account = firm.create_account!(credit_limit: 1000)
306
313
  assert_equal account, firm.reload.account
307
314
  end
308
315
 
309
316
  def test_create_association_with_bang_failing
310
- firm = Firm.create(:name => "GlobalMegaCorp")
317
+ firm = Firm.create(name: "GlobalMegaCorp")
311
318
  assert_raise ActiveRecord::RecordInvalid do
312
319
  firm.create_account!
313
320
  end
@@ -319,13 +326,22 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
319
326
  end
320
327
 
321
328
  def test_create_with_inexistent_foreign_key_failing
322
- firm = Firm.create(name: 'GlobalMegaCorp')
329
+ firm = Firm.create(name: "GlobalMegaCorp")
323
330
 
324
331
  assert_raises(ActiveRecord::UnknownAttributeError) do
325
332
  firm.create_account_with_inexistent_foreign_key
326
333
  end
327
334
  end
328
335
 
336
+ def test_create_when_parent_is_new_raises
337
+ firm = Firm.new
338
+ error = assert_raise(ActiveRecord::RecordNotSaved) do
339
+ firm.create_account
340
+ end
341
+
342
+ assert_equal "You cannot call create unless the parent is saved", error.message
343
+ end
344
+
329
345
  def test_reload_association
330
346
  odegy = companies(:odegy)
331
347
 
@@ -336,6 +352,29 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
336
352
  assert_equal 80, odegy.reload_account.credit_limit
337
353
  end
338
354
 
355
+ def test_reload_association_with_query_cache
356
+ odegy_id = companies(:odegy).id
357
+
358
+ connection = ActiveRecord::Base.connection
359
+ connection.enable_query_cache!
360
+ connection.clear_query_cache
361
+
362
+ # Populate the cache with a query
363
+ odegy = Company.find(odegy_id)
364
+ # Populate the cache with a second query
365
+ odegy.account
366
+
367
+ assert_equal 2, connection.query_cache.size
368
+
369
+ # Clear the cache and fetch the account again, populating the cache with a query
370
+ assert_queries(1) { odegy.reload_account }
371
+
372
+ # This query is not cached anymore, so it should make a real SQL query
373
+ assert_queries(1) { Company.find(odegy_id) }
374
+ ensure
375
+ ActiveRecord::Base.connection.disable_query_cache!
376
+ end
377
+
339
378
  def test_build
340
379
  firm = Firm.new("name" => "GlobalMegaCorp")
341
380
  firm.save
@@ -375,7 +414,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
375
414
 
376
415
  def test_finding_with_interpolated_condition
377
416
  firm = Firm.first
378
- superior = firm.clients.create(:name => 'SuperiorCo')
417
+ superior = firm.clients.create(name: "SuperiorCo")
379
418
  superior.rating = 10
380
419
  superior.save
381
420
  assert_equal 10, firm.clients_with_interpolated_conditions.first.rating
@@ -384,7 +423,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
384
423
  def test_assignment_before_child_saved
385
424
  firm = Firm.find(1)
386
425
  firm.account = a = Account.new("credit_limit" => 1000)
387
- assert a.persisted?
426
+ assert_predicate a, :persisted?
388
427
  assert_equal a, firm.account
389
428
  assert_equal a, firm.account
390
429
  firm.association(:account).reload
@@ -392,7 +431,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
392
431
  end
393
432
 
394
433
  def test_save_still_works_after_accessing_nil_has_one
395
- jp = Company.new :name => 'Jaded Pixel'
434
+ jp = Company.new name: "Jaded Pixel"
396
435
  jp.dummy_account.nil?
397
436
 
398
437
  assert_nothing_raised do
@@ -402,7 +441,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
402
441
 
403
442
  def test_cant_save_readonly_association
404
443
  assert_raise(ActiveRecord::ReadOnlyRecord) { companies(:first_firm).readonly_account.save! }
405
- assert companies(:first_firm).readonly_account.readonly?
444
+ assert_predicate companies(:first_firm).readonly_account, :readonly?
406
445
  end
407
446
 
408
447
  def test_has_one_proxy_should_not_respond_to_private_methods
@@ -421,14 +460,14 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
421
460
 
422
461
  assert_nothing_raised do
423
462
  Firm.find(@firm.id).save!
424
- Firm.all.merge!(:includes => :account).find(@firm.id).save!
463
+ Firm.all.merge!(includes: :account).find(@firm.id).save!
425
464
  end
426
465
 
427
466
  @firm.account.destroy
428
467
 
429
468
  assert_nothing_raised do
430
469
  Firm.find(@firm.id).save!
431
- Firm.all.merge!(:includes => :account).find(@firm.id).save!
470
+ Firm.all.merge!(includes: :account).find(@firm.id).save!
432
471
  end
433
472
  end
434
473
 
@@ -440,12 +479,12 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
440
479
 
441
480
  def test_create_respects_hash_condition
442
481
  account = companies(:first_firm).create_account_limit_500_with_hash_conditions
443
- assert account.persisted?
482
+ assert_predicate account, :persisted?
444
483
  assert_equal 500, account.credit_limit
445
484
  end
446
485
 
447
486
  def test_attributes_are_being_set_when_initialized_from_has_one_association_with_where_clause
448
- new_account = companies(:first_firm).build_account(:firm_name => 'Account')
487
+ new_account = companies(:first_firm).build_account(firm_name: "Account")
449
488
  assert_equal new_account.firm_name, "Account"
450
489
  end
451
490
 
@@ -457,9 +496,9 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
457
496
  new_ship = pirate.create_ship
458
497
  assert_not_equal ships(:black_pearl), new_ship
459
498
  assert_equal new_ship, pirate.ship
460
- assert new_ship.new_record?
499
+ assert_predicate new_ship, :new_record?
461
500
  assert_nil orig_ship.pirate_id
462
- assert !orig_ship.changed? # check it was saved
501
+ assert_not orig_ship.changed? # check it was saved
463
502
  end
464
503
 
465
504
  def test_creation_failure_with_dependent_option
@@ -467,8 +506,8 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
467
506
  orig_ship = pirate.dependent_ship
468
507
 
469
508
  new_ship = pirate.create_dependent_ship
470
- assert new_ship.new_record?
471
- assert orig_ship.destroyed?
509
+ assert_predicate new_ship, :new_record?
510
+ assert_predicate orig_ship, :destroyed?
472
511
  end
473
512
 
474
513
  def test_creation_failure_due_to_new_record_should_raise_error
@@ -488,14 +527,14 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
488
527
  pirate = pirates(:blackbeard)
489
528
  pirate.ship.name = nil
490
529
 
491
- assert !pirate.ship.valid?
530
+ assert_not_predicate pirate.ship, :valid?
492
531
  error = assert_raise(ActiveRecord::RecordNotSaved) do
493
532
  pirate.ship = ships(:interceptor)
494
533
  end
495
534
 
496
535
  assert_equal ships(:black_pearl), pirate.ship
497
536
  assert_equal pirate.id, pirate.ship.pirate_id
498
- assert_equal "Failed to remove the existing associated ship. " +
537
+ assert_equal "Failed to remove the existing associated ship. " \
499
538
  "The record failed to save after its foreign key was set to nil.", error.message
500
539
  end
501
540
 
@@ -515,63 +554,63 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
515
554
  end
516
555
 
517
556
  def test_association_keys_bypass_attribute_protection
518
- car = Car.create(:name => 'honda')
557
+ car = Car.create(name: "honda")
519
558
 
520
559
  bulb = car.build_bulb
521
560
  assert_equal car.id, bulb.car_id
522
561
 
523
- bulb = car.build_bulb :car_id => car.id + 1
562
+ bulb = car.build_bulb car_id: car.id + 1
524
563
  assert_equal car.id, bulb.car_id
525
564
 
526
565
  bulb = car.create_bulb
527
566
  assert_equal car.id, bulb.car_id
528
567
 
529
- bulb = car.create_bulb :car_id => car.id + 1
568
+ bulb = car.create_bulb car_id: car.id + 1
530
569
  assert_equal car.id, bulb.car_id
531
570
  end
532
571
 
533
572
  def test_association_protect_foreign_key
534
- pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?")
573
+ pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?")
535
574
 
536
575
  ship = pirate.build_ship
537
576
  assert_equal pirate.id, ship.pirate_id
538
577
 
539
- ship = pirate.build_ship :pirate_id => pirate.id + 1
578
+ ship = pirate.build_ship pirate_id: pirate.id + 1
540
579
  assert_equal pirate.id, ship.pirate_id
541
580
 
542
581
  ship = pirate.create_ship
543
582
  assert_equal pirate.id, ship.pirate_id
544
583
 
545
- ship = pirate.create_ship :pirate_id => pirate.id + 1
584
+ ship = pirate.create_ship pirate_id: pirate.id + 1
546
585
  assert_equal pirate.id, ship.pirate_id
547
586
  end
548
587
 
549
588
  def test_build_with_block
550
- car = Car.create(:name => 'honda')
589
+ car = Car.create(name: "honda")
551
590
 
552
- bulb = car.build_bulb{ |b| b.color = 'Red' }
553
- assert_equal 'RED!', bulb.color
591
+ bulb = car.build_bulb { |b| b.color = "Red" }
592
+ assert_equal "RED!", bulb.color
554
593
  end
555
594
 
556
595
  def test_create_with_block
557
- car = Car.create(:name => 'honda')
596
+ car = Car.create(name: "honda")
558
597
 
559
- bulb = car.create_bulb{ |b| b.color = 'Red' }
560
- assert_equal 'RED!', bulb.color
598
+ bulb = car.create_bulb { |b| b.color = "Red" }
599
+ assert_equal "RED!", bulb.color
561
600
  end
562
601
 
563
602
  def test_create_bang_with_block
564
- car = Car.create(:name => 'honda')
603
+ car = Car.create(name: "honda")
565
604
 
566
- bulb = car.create_bulb!{ |b| b.color = 'Red' }
567
- assert_equal 'RED!', bulb.color
605
+ bulb = car.create_bulb! { |b| b.color = "Red" }
606
+ assert_equal "RED!", bulb.color
568
607
  end
569
608
 
570
609
  def test_association_attributes_are_available_to_after_initialize
571
- car = Car.create(:name => 'honda')
610
+ car = Car.create(name: "honda")
572
611
  bulb = car.create_bulb
573
612
 
574
- assert_equal car.id, bulb.attributes_after_initialize['car_id']
613
+ assert_equal car.id, bulb.attributes_after_initialize["car_id"]
575
614
  end
576
615
 
577
616
  def test_has_one_transaction
@@ -591,36 +630,36 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
591
630
 
592
631
  def test_has_one_assignment_dont_trigger_save_on_change_of_same_object
593
632
  pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?")
594
- ship = pirate.build_ship(name: 'old name')
633
+ ship = pirate.build_ship(name: "old name")
595
634
  ship.save!
596
635
 
597
- ship.name = 'new name'
598
- assert ship.changed?
636
+ ship.name = "new name"
637
+ assert_predicate ship, :changed?
599
638
  assert_queries(1) do
600
639
  # One query for updating name, not triggering query for updating pirate_id
601
640
  pirate.ship = ship
602
641
  end
603
642
 
604
- assert_equal 'new name', pirate.ship.reload.name
643
+ assert_equal "new name", pirate.ship.reload.name
605
644
  end
606
645
 
607
646
  def test_has_one_assignment_triggers_save_on_change_on_replacing_object
608
647
  pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?")
609
- ship = pirate.build_ship(name: 'old name')
648
+ ship = pirate.build_ship(name: "old name")
610
649
  ship.save!
611
650
 
612
- new_ship = Ship.create(name: 'new name')
651
+ new_ship = Ship.create(name: "new name")
613
652
  assert_queries(2) do
614
- # One query for updating name and second query for updating pirate_id
653
+ # One query to nullify the old ship, one query to update the new ship
615
654
  pirate.ship = new_ship
616
655
  end
617
656
 
618
- assert_equal 'new name', pirate.ship.reload.name
657
+ assert_equal "new name", pirate.ship.reload.name
619
658
  end
620
659
 
621
660
  def test_has_one_autosave_with_primary_key_manually_set
622
- post = Post.create(id: 1234, title: "Some title", body: 'Some content')
623
- author = Author.new(id: 33, name: 'Hank Moody')
661
+ post = Post.create(id: 1234, title: "Some title", body: "Some content")
662
+ author = Author.new(id: 33, name: "Hank Moody")
624
663
 
625
664
  author.post = post
626
665
  author.save
@@ -631,7 +670,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
631
670
  end
632
671
 
633
672
  def test_has_one_loading_for_new_record
634
- post = Post.create!(author_id: 42, title: 'foo', body: 'bar')
673
+ post = Post.create!(author_id: 42, title: "foo", body: "bar")
635
674
  author = Author.new(id: 42)
636
675
  assert_equal post, author.post
637
676
  end
@@ -645,17 +684,18 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
645
684
  end
646
685
 
647
686
  def test_with_polymorphic_has_one_with_custom_columns_name
648
- post = Post.create! :title => 'foo', :body => 'bar'
687
+ post = Post.create! title: "foo", body: "bar"
649
688
  image = Image.create!
650
689
 
651
690
  post.main_image = image
652
691
  post.reload
653
692
 
654
693
  assert_equal image, post.main_image
694
+ assert_equal post, image.imageable
655
695
  end
656
696
 
657
- test 'dangerous association name raises ArgumentError' do
658
- [:errors, 'errors', :save, 'save'].each do |name|
697
+ test "dangerous association name raises ArgumentError" do
698
+ [:errors, "errors", :save, "save"].each do |name|
659
699
  assert_raises(ArgumentError, "Association #{name} should not be allowed") do
660
700
  Class.new(ActiveRecord::Base) do
661
701
  has_one name
@@ -664,21 +704,69 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
664
704
  end
665
705
  end
666
706
 
667
- def test_association_force_reload_with_only_true_is_deprecated
668
- firm = Firm.find(1)
707
+ def test_has_one_with_touch_option_on_create
708
+ assert_queries(3) {
709
+ Club.create(name: "1000 Oaks", membership_attributes: { favourite: true })
710
+ }
711
+ end
712
+
713
+ def test_polymorphic_has_one_with_touch_option_on_create_wont_cache_association_so_fetching_after_transaction_commit_works
714
+ assert_queries(4) {
715
+ chef = Chef.create(employable: DrinkDesignerWithPolymorphicTouchChef.new)
716
+ employable = chef.employable
717
+
718
+ assert_equal chef, employable.chef
719
+ }
720
+ end
721
+
722
+ def test_polymorphic_has_one_with_touch_option_on_update_will_touch_record_by_fetching_from_database_if_needed
723
+ DrinkDesignerWithPolymorphicTouchChef.create(chef: Chef.new)
724
+ designer = DrinkDesignerWithPolymorphicTouchChef.last
725
+
726
+ assert_queries(3) {
727
+ designer.update(name: "foo")
728
+ }
729
+ end
669
730
 
670
- assert_deprecated("call `reload_account` instead") { firm.account(true) }
731
+ def test_has_one_with_touch_option_on_update
732
+ new_club = Club.create(name: "1000 Oaks")
733
+ new_club.create_membership
734
+
735
+ assert_queries(2) { new_club.update(name: "Effingut") }
736
+ end
737
+
738
+ def test_has_one_with_touch_option_on_touch
739
+ new_club = Club.create(name: "1000 Oaks")
740
+ new_club.create_membership
741
+
742
+ assert_queries(1) { new_club.touch }
743
+ end
744
+
745
+ def test_has_one_with_touch_option_on_destroy
746
+ new_club = Club.create(name: "1000 Oaks")
747
+ new_club.create_membership
748
+
749
+ assert_queries(2) { new_club.destroy }
750
+ end
751
+
752
+ def test_has_one_with_touch_option_on_empty_update
753
+ new_club = Club.create(name: "1000 Oaks")
754
+ new_club.create_membership
755
+
756
+ assert_no_queries { new_club.save }
671
757
  end
672
758
 
673
759
  class SpecialBook < ActiveRecord::Base
674
760
  self.table_name = "books"
675
761
  belongs_to :author, class_name: "SpecialAuthor"
676
762
  has_one :subscription, class_name: "SpecialSupscription", foreign_key: "subscriber_id"
763
+
764
+ enum status: [:proposed, :written, :published]
677
765
  end
678
766
 
679
767
  class SpecialAuthor < ActiveRecord::Base
680
- self.table_name = 'authors'
681
- has_one :book, class_name: 'SpecialBook', foreign_key: 'author_id'
768
+ self.table_name = "authors"
769
+ has_one :book, class_name: "SpecialBook", foreign_key: "author_id"
682
770
  end
683
771
 
684
772
  class SpecialSupscription < ActiveRecord::Base
@@ -686,15 +774,16 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
686
774
  belongs_to :book, class_name: "SpecialBook"
687
775
  end
688
776
 
689
- def test_assocation_enum_works_properly
690
- author = SpecialAuthor.create!(name: 'Test')
691
- book = SpecialBook.create!(status: 'published')
777
+ def test_association_enum_works_properly
778
+ author = SpecialAuthor.create!(name: "Test")
779
+ book = SpecialBook.create!(status: "published")
692
780
  author.book = book
693
781
 
694
- refute_equal 0, SpecialAuthor.joins(:book).where(books: { status: 'published' } ).count
782
+ assert_equal "published", book.status
783
+ assert_not_equal 0, SpecialAuthor.joins(:book).where(books: { status: "published" }).count
695
784
  end
696
785
 
697
- def test_assocation_enum_works_properly_with_nested_join
786
+ def test_association_enum_works_properly_with_nested_join
698
787
  author = SpecialAuthor.create!(name: "Test")
699
788
  book = SpecialBook.create!(status: "published")
700
789
  author.book = book
@@ -704,4 +793,80 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
704
793
  SpecialAuthor.joins(book: :subscription).where.not(where_clause)
705
794
  end
706
795
  end
796
+
797
+ class DestroyByParentBook < ActiveRecord::Base
798
+ self.table_name = "books"
799
+ belongs_to :author, class_name: "DestroyByParentAuthor"
800
+ before_destroy :dont, unless: :destroyed_by_association
801
+
802
+ def dont
803
+ throw(:abort)
804
+ end
805
+ end
806
+
807
+ class DestroyByParentAuthor < ActiveRecord::Base
808
+ self.table_name = "authors"
809
+ has_one :book, class_name: "DestroyByParentBook", foreign_key: "author_id", dependent: :destroy
810
+ end
811
+
812
+ test "destroyed_by_association set in child destroy callback on parent destroy" do
813
+ author = DestroyByParentAuthor.create!(name: "Test")
814
+ book = DestroyByParentBook.create!(author: author)
815
+
816
+ author.destroy
817
+
818
+ assert_not DestroyByParentBook.exists?(book.id)
819
+ end
820
+
821
+ test "destroyed_by_association set in child destroy callback on replace" do
822
+ author = DestroyByParentAuthor.create!(name: "Test")
823
+ book = DestroyByParentBook.create!(author: author)
824
+
825
+ author.book = DestroyByParentBook.create!
826
+ author.save!
827
+
828
+ assert_not DestroyByParentBook.exists?(book.id)
829
+ end
830
+
831
+ class UndestroyableBook < ActiveRecord::Base
832
+ self.table_name = "books"
833
+ belongs_to :author, class_name: "DestroyableAuthor"
834
+ before_destroy :dont
835
+
836
+ def dont
837
+ throw(:abort)
838
+ end
839
+ end
840
+
841
+ class DestroyableAuthor < ActiveRecord::Base
842
+ self.table_name = "authors"
843
+ has_one :book, class_name: "UndestroyableBook", foreign_key: "author_id", dependent: :destroy
844
+ end
845
+
846
+ def test_dependency_should_halt_parent_destruction
847
+ author = DestroyableAuthor.create!(name: "Test")
848
+ UndestroyableBook.create!(author: author)
849
+
850
+ assert_no_difference ["DestroyableAuthor.count", "UndestroyableBook.count"] do
851
+ assert_not author.destroy
852
+ end
853
+ end
854
+
855
+ class SpecialCar < ActiveRecord::Base
856
+ self.table_name = "cars"
857
+ has_one :special_bulb, inverse_of: :car, dependent: :destroy, class_name: "SpecialBulb", foreign_key: "car_id"
858
+ end
859
+
860
+ class SpecialBulb < ActiveRecord::Base
861
+ self.table_name = "bulbs"
862
+ belongs_to :car, inverse_of: :special_bulb, touch: true, class_name: "SpecialCar"
863
+ end
864
+
865
+ def test_has_one_with_touch_option_on_nonpersisted_built_associations_doesnt_update_parent
866
+ car = SpecialCar.create(name: "honda")
867
+ assert_queries(1) do
868
+ car.build_special_bulb
869
+ car.build_special_bulb
870
+ end
871
+ end
707
872
  end