ibm_db 4.0.0-x86-mingw32 → 5.1.0-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 (576) hide show
  1. checksums.yaml +5 -5
  2. data/MANIFEST +14 -14
  3. data/README +208 -208
  4. data/ext/Makefile +269 -0
  5. data/ext/Makefile.nt32 +181 -181
  6. data/ext/Makefile.nt32.191 +212 -212
  7. data/ext/extconf.rb +322 -291
  8. data/ext/gil_release_version.h +3 -0
  9. data/ext/ibm_db-i386-mingw32.def +2 -0
  10. data/ext/ibm_db.c +11879 -11887
  11. data/ext/ibm_db.o +0 -0
  12. data/ext/ibm_db.so +0 -0
  13. data/ext/mkmf.log +110 -0
  14. data/ext/ruby_ibm_db.h +241 -241
  15. data/ext/ruby_ibm_db_cli.c +866 -866
  16. data/ext/ruby_ibm_db_cli.h +500 -500
  17. data/ext/ruby_ibm_db_cli.o +0 -0
  18. data/ext/unicode_support_version.h +3 -0
  19. data/init.rb +41 -41
  20. data/lib/IBM_DB.rb +27 -27
  21. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +3593 -3452
  22. data/lib/active_record/connection_adapters/ibmdb_adapter.rb +5 -5
  23. data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -328
  24. data/lib/mswin32/ibm_db.rb +94 -90
  25. data/lib/mswin32/rb2x/i386/ruby26/ibm_db.so +0 -0
  26. data/lib/mswin32/rb2x/i386/ruby27/ibm_db.so +0 -0
  27. data/test/active_record/connection_adapters/fake_adapter.rb +49 -49
  28. data/test/assets/example.log +1 -1
  29. data/test/assets/test.txt +1 -1
  30. data/test/cases/adapter_test.rb +351 -351
  31. data/test/cases/adapters/mysql2/active_schema_test.rb +193 -193
  32. data/test/cases/adapters/mysql2/bind_parameter_test.rb +50 -50
  33. data/test/cases/adapters/mysql2/boolean_test.rb +100 -100
  34. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +63 -63
  35. data/test/cases/adapters/mysql2/charset_collation_test.rb +54 -54
  36. data/test/cases/adapters/mysql2/connection_test.rb +210 -210
  37. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +45 -45
  38. data/test/cases/adapters/mysql2/enum_test.rb +26 -26
  39. data/test/cases/adapters/mysql2/explain_test.rb +21 -21
  40. data/test/cases/adapters/mysql2/json_test.rb +195 -195
  41. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +83 -83
  42. data/test/cases/adapters/mysql2/reserved_word_test.rb +152 -152
  43. data/test/cases/adapters/mysql2/schema_migrations_test.rb +59 -59
  44. data/test/cases/adapters/mysql2/schema_test.rb +126 -126
  45. data/test/cases/adapters/mysql2/sp_test.rb +36 -36
  46. data/test/cases/adapters/mysql2/sql_types_test.rb +14 -14
  47. data/test/cases/adapters/mysql2/table_options_test.rb +42 -42
  48. data/test/cases/adapters/mysql2/unsigned_type_test.rb +66 -66
  49. data/test/cases/adapters/postgresql/active_schema_test.rb +98 -98
  50. data/test/cases/adapters/postgresql/array_test.rb +339 -339
  51. data/test/cases/adapters/postgresql/bit_string_test.rb +82 -82
  52. data/test/cases/adapters/postgresql/bytea_test.rb +134 -134
  53. data/test/cases/adapters/postgresql/case_insensitive_test.rb +26 -26
  54. data/test/cases/adapters/postgresql/change_schema_test.rb +38 -38
  55. data/test/cases/adapters/postgresql/cidr_test.rb +25 -25
  56. data/test/cases/adapters/postgresql/citext_test.rb +78 -78
  57. data/test/cases/adapters/postgresql/collation_test.rb +53 -53
  58. data/test/cases/adapters/postgresql/composite_test.rb +132 -132
  59. data/test/cases/adapters/postgresql/connection_test.rb +257 -257
  60. data/test/cases/adapters/postgresql/datatype_test.rb +92 -92
  61. data/test/cases/adapters/postgresql/domain_test.rb +47 -47
  62. data/test/cases/adapters/postgresql/enum_test.rb +91 -91
  63. data/test/cases/adapters/postgresql/explain_test.rb +20 -20
  64. data/test/cases/adapters/postgresql/extension_migration_test.rb +63 -63
  65. data/test/cases/adapters/postgresql/full_text_test.rb +44 -44
  66. data/test/cases/adapters/postgresql/geometric_test.rb +378 -378
  67. data/test/cases/adapters/postgresql/hstore_test.rb +382 -382
  68. data/test/cases/adapters/postgresql/infinity_test.rb +69 -69
  69. data/test/cases/adapters/postgresql/integer_test.rb +25 -25
  70. data/test/cases/adapters/postgresql/json_test.rb +237 -237
  71. data/test/cases/adapters/postgresql/ltree_test.rb +53 -53
  72. data/test/cases/adapters/postgresql/money_test.rb +96 -96
  73. data/test/cases/adapters/postgresql/network_test.rb +94 -94
  74. data/test/cases/adapters/postgresql/numbers_test.rb +49 -49
  75. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +405 -405
  76. data/test/cases/adapters/postgresql/prepared_statements_test.rb +22 -22
  77. data/test/cases/adapters/postgresql/quoting_test.rb +44 -44
  78. data/test/cases/adapters/postgresql/range_test.rb +343 -343
  79. data/test/cases/adapters/postgresql/referential_integrity_test.rb +111 -111
  80. data/test/cases/adapters/postgresql/rename_table_test.rb +34 -34
  81. data/test/cases/adapters/postgresql/schema_authorization_test.rb +119 -119
  82. data/test/cases/adapters/postgresql/schema_test.rb +597 -597
  83. data/test/cases/adapters/postgresql/serial_test.rb +154 -154
  84. data/test/cases/adapters/postgresql/statement_pool_test.rb +41 -41
  85. data/test/cases/adapters/postgresql/timestamp_test.rb +90 -90
  86. data/test/cases/adapters/postgresql/type_lookup_test.rb +33 -33
  87. data/test/cases/adapters/postgresql/utils_test.rb +62 -62
  88. data/test/cases/adapters/postgresql/uuid_test.rb +294 -294
  89. data/test/cases/adapters/postgresql/xml_test.rb +54 -54
  90. data/test/cases/adapters/sqlite3/collation_test.rb +53 -53
  91. data/test/cases/adapters/sqlite3/copy_table_test.rb +98 -98
  92. data/test/cases/adapters/sqlite3/explain_test.rb +21 -21
  93. data/test/cases/adapters/sqlite3/quoting_test.rb +101 -101
  94. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +441 -441
  95. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +24 -24
  96. data/test/cases/adapters/sqlite3/statement_pool_test.rb +20 -20
  97. data/test/cases/aggregations_test.rb +168 -168
  98. data/test/cases/ar_schema_test.rb +146 -146
  99. data/test/cases/associations/association_scope_test.rb +16 -16
  100. data/test/cases/associations/belongs_to_associations_test.rb +1141 -1141
  101. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +41 -41
  102. data/test/cases/associations/callbacks_test.rb +190 -190
  103. data/test/cases/associations/cascaded_eager_loading_test.rb +188 -188
  104. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +36 -36
  105. data/test/cases/associations/eager_load_nested_include_test.rb +126 -126
  106. data/test/cases/associations/eager_singularization_test.rb +148 -148
  107. data/test/cases/associations/eager_test.rb +1514 -1514
  108. data/test/cases/associations/extension_test.rb +87 -87
  109. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +1004 -1004
  110. data/test/cases/associations/has_many_associations_test.rb +2501 -2501
  111. data/test/cases/associations/has_many_through_associations_test.rb +1271 -1271
  112. data/test/cases/associations/has_one_associations_test.rb +707 -707
  113. data/test/cases/associations/has_one_through_associations_test.rb +383 -383
  114. data/test/cases/associations/inner_join_association_test.rb +139 -139
  115. data/test/cases/associations/inverse_associations_test.rb +733 -733
  116. data/test/cases/associations/join_model_test.rb +777 -777
  117. data/test/cases/associations/left_outer_join_association_test.rb +88 -88
  118. data/test/cases/associations/nested_through_associations_test.rb +579 -579
  119. data/test/cases/associations/required_test.rb +102 -102
  120. data/test/cases/associations_test.rb +385 -385
  121. data/test/cases/attribute_decorators_test.rb +126 -125
  122. data/test/cases/attribute_methods/read_test.rb +60 -60
  123. data/test/cases/attribute_methods_test.rb +1009 -1009
  124. data/test/cases/attribute_set_test.rb +270 -270
  125. data/test/cases/attribute_test.rb +246 -246
  126. data/test/cases/attributes_test.rb +253 -253
  127. data/test/cases/autosave_association_test.rb +1708 -1708
  128. data/test/cases/base_test.rb +1713 -1713
  129. data/test/cases/batches_test.rb +489 -489
  130. data/test/cases/binary_test.rb +44 -44
  131. data/test/cases/bind_parameter_test.rb +110 -110
  132. data/test/cases/cache_key_test.rb +26 -25
  133. data/test/cases/calculations_test.rb +798 -798
  134. data/test/cases/callbacks_test.rb +636 -636
  135. data/test/cases/clone_test.rb +40 -40
  136. data/test/cases/coders/json_test.rb +15 -15
  137. data/test/cases/coders/yaml_column_test.rb +63 -63
  138. data/test/cases/collection_cache_key_test.rb +115 -115
  139. data/test/cases/column_alias_test.rb +17 -17
  140. data/test/cases/column_definition_test.rb +92 -92
  141. data/test/cases/comment_test.rb +145 -143
  142. data/test/cases/connection_adapters/adapter_leasing_test.rb +56 -56
  143. data/test/cases/connection_adapters/connection_handler_test.rb +160 -160
  144. data/test/cases/connection_adapters/connection_specification_test.rb +12 -12
  145. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +255 -255
  146. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +69 -69
  147. data/test/cases/connection_adapters/quoting_test.rb +13 -13
  148. data/test/cases/connection_adapters/schema_cache_test.rb +61 -61
  149. data/test/cases/connection_adapters/type_lookup_test.rb +118 -118
  150. data/test/cases/connection_management_test.rb +112 -112
  151. data/test/cases/connection_pool_test.rb +521 -521
  152. data/test/cases/connection_specification/resolver_test.rb +131 -131
  153. data/test/cases/core_test.rb +112 -112
  154. data/test/cases/counter_cache_test.rb +214 -214
  155. data/test/cases/custom_locking_test.rb +17 -17
  156. data/test/cases/database_statements_test.rb +34 -34
  157. data/test/cases/date_test.rb +44 -44
  158. data/test/cases/date_time_precision_test.rb +107 -106
  159. data/test/cases/date_time_test.rb +61 -61
  160. data/test/cases/defaults_test.rb +219 -218
  161. data/test/cases/dirty_test.rb +763 -763
  162. data/test/cases/disconnected_test.rb +30 -30
  163. data/test/cases/dup_test.rb +157 -157
  164. data/test/cases/enum_test.rb +444 -444
  165. data/test/cases/errors_test.rb +16 -16
  166. data/test/cases/explain_subscriber_test.rb +64 -64
  167. data/test/cases/explain_test.rb +87 -87
  168. data/test/cases/finder_respond_to_test.rb +60 -60
  169. data/test/cases/finder_test.rb +1294 -1294
  170. data/test/cases/fixture_set/file_test.rb +156 -156
  171. data/test/cases/fixtures_test.rb +988 -988
  172. data/test/cases/forbidden_attributes_protection_test.rb +165 -165
  173. data/test/cases/habtm_destroy_order_test.rb +61 -61
  174. data/test/cases/helper.rb +204 -204
  175. data/test/cases/hot_compatibility_test.rb +142 -142
  176. data/test/cases/i18n_test.rb +45 -45
  177. data/test/cases/inheritance_test.rb +606 -606
  178. data/test/cases/integration_test.rb +155 -155
  179. data/test/cases/invalid_connection_test.rb +24 -24
  180. data/test/cases/invertible_migration_test.rb +387 -387
  181. data/test/cases/json_serialization_test.rb +311 -311
  182. data/test/cases/locking_test.rb +493 -493
  183. data/test/cases/log_subscriber_test.rb +225 -225
  184. data/test/cases/migration/change_schema_test.rb +458 -458
  185. data/test/cases/migration/change_table_test.rb +256 -256
  186. data/test/cases/migration/column_attributes_test.rb +176 -176
  187. data/test/cases/migration/column_positioning_test.rb +56 -56
  188. data/test/cases/migration/columns_test.rb +310 -310
  189. data/test/cases/migration/command_recorder_test.rb +350 -350
  190. data/test/cases/migration/compatibility_test.rb +118 -118
  191. data/test/cases/migration/create_join_table_test.rb +157 -157
  192. data/test/cases/migration/foreign_key_test.rb +362 -360
  193. data/test/cases/migration/helper.rb +39 -39
  194. data/test/cases/migration/index_test.rb +218 -218
  195. data/test/cases/migration/logger_test.rb +36 -36
  196. data/test/cases/migration/pending_migrations_test.rb +52 -52
  197. data/test/cases/migration/references_foreign_key_test.rb +221 -216
  198. data/test/cases/migration/references_index_test.rb +101 -101
  199. data/test/cases/migration/references_statements_test.rb +136 -136
  200. data/test/cases/migration/rename_table_test.rb +93 -93
  201. data/test/cases/migration_test.rb +1157 -1157
  202. data/test/cases/migrator_test.rb +471 -470
  203. data/test/cases/mixin_test.rb +68 -68
  204. data/test/cases/modules_test.rb +172 -172
  205. data/test/cases/multiparameter_attributes_test.rb +372 -372
  206. data/test/cases/multiple_db_test.rb +122 -122
  207. data/test/cases/nested_attributes_test.rb +1098 -1098
  208. data/test/cases/nested_attributes_with_callbacks_test.rb +144 -144
  209. data/test/cases/persistence_test.rb +1001 -1001
  210. data/test/cases/pooled_connections_test.rb +81 -81
  211. data/test/cases/primary_keys_test.rb +376 -376
  212. data/test/cases/query_cache_test.rb +446 -446
  213. data/test/cases/quoting_test.rb +202 -202
  214. data/test/cases/readonly_test.rb +119 -119
  215. data/test/cases/reaper_test.rb +85 -85
  216. data/test/cases/reflection_test.rb +509 -509
  217. data/test/cases/relation/delegation_test.rb +63 -63
  218. data/test/cases/relation/merging_test.rb +157 -157
  219. data/test/cases/relation/mutation_test.rb +183 -183
  220. data/test/cases/relation/or_test.rb +92 -92
  221. data/test/cases/relation/predicate_builder_test.rb +16 -16
  222. data/test/cases/relation/record_fetch_warning_test.rb +40 -40
  223. data/test/cases/relation/where_chain_test.rb +105 -105
  224. data/test/cases/relation/where_clause_test.rb +182 -182
  225. data/test/cases/relation/where_test.rb +322 -322
  226. data/test/cases/relation_test.rb +328 -328
  227. data/test/cases/relations_test.rb +2026 -2026
  228. data/test/cases/reload_models_test.rb +22 -22
  229. data/test/cases/result_test.rb +90 -90
  230. data/test/cases/sanitize_test.rb +176 -176
  231. data/test/cases/schema_dumper_test.rb +457 -457
  232. data/test/cases/schema_loading_test.rb +52 -52
  233. data/test/cases/scoping/default_scoping_test.rb +528 -528
  234. data/test/cases/scoping/named_scoping_test.rb +561 -561
  235. data/test/cases/scoping/relation_scoping_test.rb +400 -400
  236. data/test/cases/secure_token_test.rb +32 -32
  237. data/test/cases/serialization_test.rb +104 -104
  238. data/test/cases/serialized_attribute_test.rb +364 -364
  239. data/test/cases/statement_cache_test.rb +136 -136
  240. data/test/cases/store_test.rb +195 -195
  241. data/test/cases/suppressor_test.rb +63 -63
  242. data/test/cases/tasks/database_tasks_test.rb +462 -462
  243. data/test/cases/tasks/mysql_rake_test.rb +345 -345
  244. data/test/cases/tasks/postgresql_rake_test.rb +304 -304
  245. data/test/cases/tasks/sqlite_rake_test.rb +220 -220
  246. data/test/cases/test_case.rb +131 -131
  247. data/test/cases/test_fixtures_test.rb +36 -36
  248. data/test/cases/time_precision_test.rb +103 -102
  249. data/test/cases/timestamp_test.rb +501 -501
  250. data/test/cases/touch_later_test.rb +121 -121
  251. data/test/cases/transaction_callbacks_test.rb +518 -518
  252. data/test/cases/transaction_isolation_test.rb +106 -106
  253. data/test/cases/transactions_test.rb +835 -834
  254. data/test/cases/type/adapter_specific_registry_test.rb +133 -133
  255. data/test/cases/type/date_time_test.rb +14 -14
  256. data/test/cases/type/integer_test.rb +27 -27
  257. data/test/cases/type/string_test.rb +22 -22
  258. data/test/cases/type/type_map_test.rb +177 -177
  259. data/test/cases/type_test.rb +39 -39
  260. data/test/cases/types_test.rb +24 -24
  261. data/test/cases/unconnected_test.rb +33 -33
  262. data/test/cases/validations/absence_validation_test.rb +73 -73
  263. data/test/cases/validations/association_validation_test.rb +97 -97
  264. data/test/cases/validations/i18n_generate_message_validation_test.rb +84 -84
  265. data/test/cases/validations/i18n_validation_test.rb +86 -86
  266. data/test/cases/validations/length_validation_test.rb +79 -79
  267. data/test/cases/validations/presence_validation_test.rb +103 -103
  268. data/test/cases/validations/uniqueness_validation_test.rb +548 -548
  269. data/test/cases/validations_repair_helper.rb +19 -19
  270. data/test/cases/validations_test.rb +194 -194
  271. data/test/cases/view_test.rb +216 -216
  272. data/test/cases/yaml_serialization_test.rb +121 -121
  273. data/test/config.example.yml +97 -97
  274. data/test/config.rb +5 -5
  275. data/test/connections/native_ibm_db/connection.rb +44 -0
  276. data/test/fixtures/accounts.yml +29 -29
  277. data/test/fixtures/admin/accounts.yml +2 -2
  278. data/test/fixtures/admin/users.yml +10 -10
  279. data/test/fixtures/author_addresses.yml +17 -17
  280. data/test/fixtures/author_favorites.yml +3 -3
  281. data/test/fixtures/authors.yml +23 -23
  282. data/test/fixtures/bad_posts.yml +9 -9
  283. data/test/fixtures/binaries.yml +133 -133
  284. data/test/fixtures/books.yml +31 -31
  285. data/test/fixtures/bulbs.yml +5 -5
  286. data/test/fixtures/cars.yml +9 -9
  287. data/test/fixtures/categories.yml +19 -19
  288. data/test/fixtures/categories/special_categories.yml +9 -9
  289. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -4
  290. data/test/fixtures/categories_ordered.yml +7 -7
  291. data/test/fixtures/categories_posts.yml +31 -31
  292. data/test/fixtures/categorizations.yml +23 -23
  293. data/test/fixtures/clubs.yml +8 -8
  294. data/test/fixtures/collections.yml +3 -3
  295. data/test/fixtures/colleges.yml +3 -3
  296. data/test/fixtures/comments.yml +65 -65
  297. data/test/fixtures/companies.yml +67 -67
  298. data/test/fixtures/computers.yml +10 -10
  299. data/test/fixtures/content.yml +3 -3
  300. data/test/fixtures/content_positions.yml +3 -3
  301. data/test/fixtures/courses.yml +8 -8
  302. data/test/fixtures/customers.yml +25 -25
  303. data/test/fixtures/dashboards.yml +6 -6
  304. data/test/fixtures/dead_parrots.yml +5 -5
  305. data/test/fixtures/developers.yml +22 -22
  306. data/test/fixtures/developers_projects.yml +16 -16
  307. data/test/fixtures/dog_lovers.yml +7 -7
  308. data/test/fixtures/dogs.yml +4 -4
  309. data/test/fixtures/doubloons.yml +3 -3
  310. data/test/fixtures/edges.yml +5 -5
  311. data/test/fixtures/entrants.yml +14 -14
  312. data/test/fixtures/essays.yml +6 -6
  313. data/test/fixtures/faces.yml +11 -11
  314. data/test/fixtures/fk_test_has_fk.yml +3 -3
  315. data/test/fixtures/fk_test_has_pk.yml +1 -1
  316. data/test/fixtures/friendships.yml +4 -4
  317. data/test/fixtures/funny_jokes.yml +10 -10
  318. data/test/fixtures/interests.yml +33 -33
  319. data/test/fixtures/items.yml +3 -3
  320. data/test/fixtures/jobs.yml +7 -7
  321. data/test/fixtures/legacy_things.yml +3 -3
  322. data/test/fixtures/live_parrots.yml +4 -4
  323. data/test/fixtures/mateys.yml +4 -4
  324. data/test/fixtures/member_details.yml +8 -8
  325. data/test/fixtures/member_types.yml +6 -6
  326. data/test/fixtures/members.yml +11 -11
  327. data/test/fixtures/memberships.yml +34 -34
  328. data/test/fixtures/men.yml +5 -5
  329. data/test/fixtures/minimalistics.yml +2 -2
  330. data/test/fixtures/minivans.yml +5 -5
  331. data/test/fixtures/mixed_case_monkeys.yml +6 -6
  332. data/test/fixtures/mixins.yml +29 -29
  333. data/test/fixtures/movies.yml +7 -7
  334. data/test/fixtures/naked/yml/accounts.yml +1 -1
  335. data/test/fixtures/naked/yml/companies.yml +1 -1
  336. data/test/fixtures/naked/yml/courses.yml +1 -1
  337. data/test/fixtures/naked/yml/parrots.yml +2 -2
  338. data/test/fixtures/naked/yml/trees.yml +3 -3
  339. data/test/fixtures/nodes.yml +29 -29
  340. data/test/fixtures/organizations.yml +5 -5
  341. data/test/fixtures/other_comments.yml +6 -6
  342. data/test/fixtures/other_dogs.yml +2 -2
  343. data/test/fixtures/other_posts.yml +7 -7
  344. data/test/fixtures/other_topics.yml +42 -42
  345. data/test/fixtures/owners.yml +9 -9
  346. data/test/fixtures/parrots.yml +27 -27
  347. data/test/fixtures/parrots_pirates.yml +7 -7
  348. data/test/fixtures/people.yml +24 -24
  349. data/test/fixtures/peoples_treasures.yml +3 -3
  350. data/test/fixtures/pets.yml +19 -19
  351. data/test/fixtures/pirates.yml +12 -15
  352. data/test/fixtures/posts.yml +80 -80
  353. data/test/fixtures/price_estimates.yml +16 -16
  354. data/test/fixtures/products.yml +4 -4
  355. data/test/fixtures/projects.yml +7 -7
  356. data/test/fixtures/ratings.yml +14 -14
  357. data/test/fixtures/readers.yml +11 -11
  358. data/test/fixtures/references.yml +17 -17
  359. data/test/fixtures/reserved_words/distinct.yml +5 -5
  360. data/test/fixtures/reserved_words/distinct_select.yml +11 -11
  361. data/test/fixtures/reserved_words/group.yml +14 -14
  362. data/test/fixtures/reserved_words/select.yml +8 -8
  363. data/test/fixtures/reserved_words/values.yml +7 -7
  364. data/test/fixtures/ships.yml +6 -6
  365. data/test/fixtures/speedometers.yml +8 -8
  366. data/test/fixtures/sponsors.yml +12 -12
  367. data/test/fixtures/string_key_objects.yml +7 -7
  368. data/test/fixtures/subscribers.yml +10 -10
  369. data/test/fixtures/subscriptions.yml +12 -12
  370. data/test/fixtures/taggings.yml +78 -78
  371. data/test/fixtures/tags.yml +11 -11
  372. data/test/fixtures/tasks.yml +7 -7
  373. data/test/fixtures/teapots.yml +3 -3
  374. data/test/fixtures/to_be_linked/accounts.yml +2 -2
  375. data/test/fixtures/to_be_linked/users.yml +10 -10
  376. data/test/fixtures/topics.yml +49 -49
  377. data/test/fixtures/toys.yml +14 -14
  378. data/test/fixtures/traffic_lights.yml +9 -9
  379. data/test/fixtures/treasures.yml +10 -10
  380. data/test/fixtures/trees.yml +3 -3
  381. data/test/fixtures/uuid_children.yml +3 -3
  382. data/test/fixtures/uuid_parents.yml +2 -2
  383. data/test/fixtures/variants.yml +4 -4
  384. data/test/fixtures/vegetables.yml +19 -19
  385. data/test/fixtures/vertices.yml +3 -3
  386. data/test/fixtures/warehouse_things.yml +2 -2
  387. data/test/fixtures/zines.yml +5 -5
  388. data/test/migrations/10_urban/9_add_expressions.rb +11 -11
  389. data/test/migrations/decimal/1_give_me_big_numbers.rb +15 -15
  390. data/test/migrations/magic/1_currencies_have_symbols.rb +12 -12
  391. data/test/migrations/missing/1000_people_have_middle_names.rb +9 -9
  392. data/test/migrations/missing/1_people_have_last_names.rb +9 -9
  393. data/test/migrations/missing/3_we_need_reminders.rb +12 -12
  394. data/test/migrations/missing/4_innocent_jointable.rb +12 -12
  395. data/test/migrations/rename/1_we_need_things.rb +11 -11
  396. data/test/migrations/rename/2_rename_things.rb +9 -9
  397. data/test/migrations/to_copy/1_people_have_hobbies.rb +9 -9
  398. data/test/migrations/to_copy/2_people_have_descriptions.rb +9 -9
  399. data/test/migrations/to_copy2/1_create_articles.rb +7 -7
  400. data/test/migrations/to_copy2/2_create_comments.rb +7 -7
  401. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +9 -9
  402. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +9 -9
  403. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +9 -9
  404. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +7 -7
  405. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +7 -7
  406. data/test/migrations/valid/1_valid_people_have_last_names.rb +9 -9
  407. data/test/migrations/valid/2_we_need_reminders.rb +12 -12
  408. data/test/migrations/valid/3_innocent_jointable.rb +12 -12
  409. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +9 -9
  410. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +12 -12
  411. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +12 -12
  412. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +9 -9
  413. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +12 -12
  414. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +12 -12
  415. data/test/migrations/version_check/20131219224947_migration_version_check.rb +8 -8
  416. data/test/models/admin.rb +5 -5
  417. data/test/models/admin/account.rb +3 -3
  418. data/test/models/admin/user.rb +40 -40
  419. data/test/models/aircraft.rb +5 -5
  420. data/test/models/arunit2_model.rb +3 -3
  421. data/test/models/author.rb +209 -209
  422. data/test/models/auto_id.rb +4 -4
  423. data/test/models/autoloadable/extra_firm.rb +2 -2
  424. data/test/models/binary.rb +2 -2
  425. data/test/models/bird.rb +12 -12
  426. data/test/models/book.rb +23 -23
  427. data/test/models/boolean.rb +2 -2
  428. data/test/models/bulb.rb +52 -52
  429. data/test/models/cake_designer.rb +3 -3
  430. data/test/models/car.rb +29 -29
  431. data/test/models/carrier.rb +2 -2
  432. data/test/models/cat.rb +10 -10
  433. data/test/models/categorization.rb +19 -19
  434. data/test/models/category.rb +35 -35
  435. data/test/models/chef.rb +8 -8
  436. data/test/models/citation.rb +3 -3
  437. data/test/models/club.rb +25 -25
  438. data/test/models/college.rb +10 -10
  439. data/test/models/column.rb +3 -3
  440. data/test/models/column_name.rb +3 -3
  441. data/test/models/comment.rb +76 -76
  442. data/test/models/company.rb +230 -230
  443. data/test/models/company_in_module.rb +98 -98
  444. data/test/models/computer.rb +3 -3
  445. data/test/models/contact.rb +41 -41
  446. data/test/models/content.rb +40 -40
  447. data/test/models/contract.rb +20 -20
  448. data/test/models/country.rb +7 -7
  449. data/test/models/course.rb +6 -6
  450. data/test/models/customer.rb +83 -83
  451. data/test/models/customer_carrier.rb +14 -14
  452. data/test/models/dashboard.rb +3 -3
  453. data/test/models/default.rb +2 -2
  454. data/test/models/department.rb +4 -4
  455. data/test/models/developer.rb +274 -274
  456. data/test/models/dog.rb +5 -5
  457. data/test/models/dog_lover.rb +5 -5
  458. data/test/models/doubloon.rb +12 -12
  459. data/test/models/drink_designer.rb +3 -3
  460. data/test/models/edge.rb +5 -5
  461. data/test/models/electron.rb +5 -5
  462. data/test/models/engine.rb +4 -4
  463. data/test/models/entrant.rb +3 -3
  464. data/test/models/essay.rb +5 -5
  465. data/test/models/event.rb +3 -3
  466. data/test/models/eye.rb +37 -37
  467. data/test/models/face.rb +9 -9
  468. data/test/models/friendship.rb +6 -6
  469. data/test/models/guid.rb +2 -2
  470. data/test/models/guitar.rb +4 -4
  471. data/test/models/hotel.rb +11 -11
  472. data/test/models/image.rb +3 -3
  473. data/test/models/interest.rb +5 -5
  474. data/test/models/invoice.rb +4 -4
  475. data/test/models/item.rb +7 -7
  476. data/test/models/job.rb +7 -7
  477. data/test/models/joke.rb +7 -7
  478. data/test/models/keyboard.rb +3 -3
  479. data/test/models/legacy_thing.rb +3 -3
  480. data/test/models/lesson.rb +11 -11
  481. data/test/models/line_item.rb +3 -3
  482. data/test/models/liquid.rb +4 -4
  483. data/test/models/man.rb +11 -11
  484. data/test/models/matey.rb +4 -4
  485. data/test/models/member.rb +42 -42
  486. data/test/models/member_detail.rb +8 -8
  487. data/test/models/member_type.rb +3 -3
  488. data/test/models/membership.rb +35 -35
  489. data/test/models/mentor.rb +2 -2
  490. data/test/models/minimalistic.rb +2 -2
  491. data/test/models/minivan.rb +9 -9
  492. data/test/models/mixed_case_monkey.rb +3 -3
  493. data/test/models/mocktail_designer.rb +2 -2
  494. data/test/models/molecule.rb +6 -6
  495. data/test/models/movie.rb +5 -5
  496. data/test/models/node.rb +5 -5
  497. data/test/models/non_primary_key.rb +2 -2
  498. data/test/models/notification.rb +3 -3
  499. data/test/models/order.rb +4 -4
  500. data/test/models/organization.rb +14 -14
  501. data/test/models/other_dog.rb +5 -5
  502. data/test/models/owner.rb +37 -37
  503. data/test/models/parrot.rb +28 -28
  504. data/test/models/person.rb +142 -142
  505. data/test/models/personal_legacy_thing.rb +4 -4
  506. data/test/models/pet.rb +18 -18
  507. data/test/models/pet_treasure.rb +6 -6
  508. data/test/models/pirate.rb +92 -92
  509. data/test/models/possession.rb +3 -3
  510. data/test/models/post.rb +273 -273
  511. data/test/models/price_estimate.rb +4 -4
  512. data/test/models/professor.rb +5 -5
  513. data/test/models/project.rb +40 -40
  514. data/test/models/publisher.rb +2 -2
  515. data/test/models/publisher/article.rb +4 -4
  516. data/test/models/publisher/magazine.rb +3 -3
  517. data/test/models/rating.rb +4 -4
  518. data/test/models/reader.rb +23 -23
  519. data/test/models/recipe.rb +3 -3
  520. data/test/models/record.rb +2 -2
  521. data/test/models/reference.rb +22 -22
  522. data/test/models/reply.rb +61 -61
  523. data/test/models/ship.rb +39 -39
  524. data/test/models/ship_part.rb +8 -8
  525. data/test/models/shop.rb +17 -17
  526. data/test/models/shop_account.rb +6 -6
  527. data/test/models/speedometer.rb +6 -6
  528. data/test/models/sponsor.rb +7 -7
  529. data/test/models/string_key_object.rb +3 -3
  530. data/test/models/student.rb +4 -4
  531. data/test/models/subject.rb +16 -16
  532. data/test/models/subscriber.rb +8 -8
  533. data/test/models/subscription.rb +4 -4
  534. data/test/models/tag.rb +13 -13
  535. data/test/models/tagging.rb +13 -13
  536. data/test/models/task.rb +5 -5
  537. data/test/models/topic.rb +118 -118
  538. data/test/models/toy.rb +6 -6
  539. data/test/models/traffic_light.rb +4 -4
  540. data/test/models/treasure.rb +14 -14
  541. data/test/models/treaty.rb +7 -7
  542. data/test/models/tree.rb +3 -3
  543. data/test/models/tuning_peg.rb +4 -4
  544. data/test/models/tyre.rb +11 -11
  545. data/test/models/user.rb +14 -14
  546. data/test/models/uuid_child.rb +3 -3
  547. data/test/models/uuid_item.rb +6 -6
  548. data/test/models/uuid_parent.rb +3 -3
  549. data/test/models/vegetables.rb +24 -24
  550. data/test/models/vehicle.rb +6 -6
  551. data/test/models/vertex.rb +9 -9
  552. data/test/models/warehouse_thing.rb +5 -5
  553. data/test/models/wheel.rb +3 -3
  554. data/test/models/without_table.rb +3 -3
  555. data/test/models/zine.rb +3 -3
  556. data/test/schema/i5/ibm_db_specific_schema.rb +137 -0
  557. data/test/schema/ids/ibm_db_specific_schema.rb +140 -0
  558. data/test/schema/luw/ibm_db_specific_schema.rb +137 -0
  559. data/test/schema/mysql2_specific_schema.rb +68 -68
  560. data/test/schema/oracle_specific_schema.rb +40 -40
  561. data/test/schema/postgresql_specific_schema.rb +114 -114
  562. data/test/schema/schema.rb +1057 -1057
  563. data/test/schema/schema.rb.original +1057 -1057
  564. data/test/schema/sqlite_specific_schema.rb +18 -18
  565. data/test/schema/zOS/ibm_db_specific_schema.rb +208 -0
  566. data/test/support/config.rb +43 -43
  567. data/test/support/connection.rb +23 -23
  568. data/test/support/connection_helper.rb +14 -14
  569. data/test/support/ddl_helper.rb +8 -8
  570. data/test/support/schema_dumping_helper.rb +20 -20
  571. data/test/support/yaml_compatibility_fixtures/rails_4_1.yml +22 -22
  572. data/test/support/yaml_compatibility_fixtures/rails_4_2_0.yml +182 -182
  573. metadata +30 -14
  574. data/lib/mswin32/rb2x/i386/ibm_db.so +0 -0
  575. data/test/fixtures/author_addresses.original +0 -11
  576. data/test/fixtures/authors.original +0 -17
@@ -1,707 +1,707 @@
1
- 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'
13
-
14
- class HasOneAssociationsTest < ActiveRecord::TestCase
15
- self.use_transactional_tests = false unless supports_savepoints?
16
- fixtures :accounts, :companies, :developers, :projects, :developers_projects, :ships, :pirates
17
-
18
- def setup
19
- Account.destroyed_account_ids.clear
20
- end
21
-
22
- 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
25
- end
26
-
27
- 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'
32
- end
33
-
34
- def test_has_one_cache_nils
35
- firm = companies(:another_firm)
36
- assert_queries(1) { assert_nil firm.account }
37
- assert_queries(0) { assert_nil firm.account }
38
-
39
- firms = Firm.all.merge!(:includes => :account).to_a
40
- assert_queries(0) { firms.each(&:account) }
41
- end
42
-
43
- def test_with_select
44
- 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
46
- end
47
-
48
- def test_finding_using_primary_key
49
- firm = companies(:first_firm)
50
- assert_equal Account.find_by_firm_id(firm.id), firm.account
51
- firm.firm_id = companies(:rails_core).id
52
- assert_equal accounts(:rails_core_account), firm.account_using_primary_key
53
- end
54
-
55
- def test_update_with_foreign_and_primary_keys
56
- firm = companies(:first_firm)
57
- account = firm.account_using_foreign_and_primary_keys
58
- assert_equal Account.find_by_firm_name(firm.name), account
59
- firm.save
60
- firm.reload
61
- assert_equal account, firm.account_using_foreign_and_primary_keys
62
- end
63
-
64
- def test_can_marshal_has_one_association_with_nil_target
65
- firm = Firm.new
66
- assert_nothing_raised do
67
- assert_equal firm.attributes, Marshal.load(Marshal.dump(firm)).attributes
68
- end
69
-
70
- firm.account
71
- assert_nothing_raised do
72
- assert_equal firm.attributes, Marshal.load(Marshal.dump(firm)).attributes
73
- end
74
- end
75
-
76
- def test_proxy_assignment
77
- company = companies(:first_firm)
78
- assert_nothing_raised { company.account = company.account }
79
- end
80
-
81
- def test_type_mismatch
82
- assert_raise(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = 1 }
83
- assert_raise(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = Project.find(1) }
84
- end
85
-
86
- def test_natural_assignment
87
- apple = Firm.create("name" => "Apple")
88
- citibank = Account.create("credit_limit" => 10)
89
- apple.account = citibank
90
- assert_equal apple.id, citibank.firm_id
91
- end
92
-
93
- def test_natural_assignment_to_nil
94
- old_account_id = companies(:first_firm).account.id
95
- companies(:first_firm).account = nil
96
- companies(:first_firm).save
97
- assert_nil companies(:first_firm).account
98
- # account is dependent, therefore is destroyed when reference to owner is lost
99
- assert_raise(ActiveRecord::RecordNotFound) { Account.find(old_account_id) }
100
- end
101
-
102
- def test_nullification_on_association_change
103
- firm = companies(:rails_core)
104
- old_account_id = firm.account.id
105
- firm.account = Account.new(:credit_limit => 5)
106
- # account is dependent with nullify, therefore its firm_id should be nil
107
- assert_nil Account.find(old_account_id).firm_id
108
- end
109
-
110
- def test_nullification_on_destroyed_association
111
- developer = Developer.create!(name: "Someone")
112
- ship = Ship.create!(name: "Planet Caravan", developer: developer)
113
- ship.destroy
114
- assert !ship.persisted?
115
- assert !developer.persisted?
116
- end
117
-
118
- def test_natural_assignment_to_nil_after_destroy
119
- firm = companies(:rails_core)
120
- old_account_id = firm.account.id
121
- firm.account.destroy
122
- firm.account = nil
123
- assert_nil companies(:rails_core).account
124
- assert_raise(ActiveRecord::RecordNotFound) { Account.find(old_account_id) }
125
- end
126
-
127
- def test_association_change_calls_delete
128
- companies(:first_firm).deletable_account = Account.new(:credit_limit => 5)
129
- assert_equal [], Account.destroyed_account_ids[companies(:first_firm).id]
130
- end
131
-
132
- def test_association_change_calls_destroy
133
- companies(:first_firm).account = Account.new(:credit_limit => 5)
134
- assert_equal [companies(:first_firm).id], Account.destroyed_account_ids[companies(:first_firm).id]
135
- end
136
-
137
- def test_natural_assignment_to_already_associated_record
138
- company = companies(:first_firm)
139
- account = accounts(:signals37)
140
- assert_equal company.account, account
141
- company.account = account
142
- company.reload
143
- account.reload
144
- assert_equal company.account, account
145
- end
146
-
147
- def test_dependence
148
- num_accounts = Account.count
149
-
150
- firm = Firm.find(1)
151
- assert_not_nil firm.account
152
- account_id = firm.account.id
153
- assert_equal [], Account.destroyed_account_ids[firm.id]
154
-
155
- firm.destroy
156
- assert_equal num_accounts - 1, Account.count
157
- assert_equal [account_id], Account.destroyed_account_ids[firm.id]
158
- end
159
-
160
- def test_exclusive_dependence
161
- num_accounts = Account.count
162
-
163
- firm = ExclusivelyDependentFirm.find(9)
164
- assert_not_nil firm.account
165
- assert_equal [], Account.destroyed_account_ids[firm.id]
166
-
167
- firm.destroy
168
- assert_equal num_accounts - 1, Account.count
169
- assert_equal [], Account.destroyed_account_ids[firm.id]
170
- end
171
-
172
- def test_dependence_with_nil_associate
173
- firm = DependentFirm.new(:name => 'nullify')
174
- firm.save!
175
- assert_nothing_raised { firm.destroy }
176
- end
177
-
178
- 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')
194
- firm.create_account(credit_limit: 10)
195
-
196
- assert_not_nil firm.account
197
-
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!
206
- end
207
-
208
- def test_restrict_with_error
209
- firm = RestrictedWithErrorFirm.create!(:name => 'restrict')
210
- firm.create_account(:credit_limit => 10)
211
-
212
- assert_not_nil firm.account
213
-
214
- firm.destroy
215
-
216
- assert !firm.errors.empty?
217
- 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?
220
- end
221
-
222
- def test_restrict_with_error_with_locale
223
- 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')
226
- firm.create_account(credit_limit: 10)
227
-
228
- assert_not_nil firm.account
229
-
230
- firm.destroy
231
-
232
- assert !firm.errors.empty?
233
- 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?
236
- ensure
237
- I18n.backend.reload!
238
- end
239
-
240
- def test_successful_build_association
241
- firm = Firm.new("name" => "GlobalMegaCorp")
242
- firm.save
243
-
244
- account = firm.build_account("credit_limit" => 1000)
245
- assert account.save
246
- assert_equal account, firm.account
247
- end
248
-
249
- def test_build_association_dont_create_transaction
250
- assert_no_queries(ignore_none: false) {
251
- Firm.new.build_account
252
- }
253
- end
254
-
255
- def test_building_the_associated_object_with_implicit_sti_base_class
256
- firm = DependentFirm.new
257
- company = firm.build_company
258
- assert_kind_of Company, company, "Expected #{company.class} to be a Company"
259
- end
260
-
261
- def test_building_the_associated_object_with_explicit_sti_base_class
262
- firm = DependentFirm.new
263
- company = firm.build_company(:type => "Company")
264
- assert_kind_of Company, company, "Expected #{company.class} to be a Company"
265
- end
266
-
267
- def test_building_the_associated_object_with_sti_subclass
268
- firm = DependentFirm.new
269
- company = firm.build_company(:type => "Client")
270
- assert_kind_of Client, company, "Expected #{company.class} to be a Client"
271
- end
272
-
273
- def test_building_the_associated_object_with_an_invalid_type
274
- firm = DependentFirm.new
275
- assert_raise(ActiveRecord::SubclassNotFound) { firm.build_company(:type => "Invalid") }
276
- end
277
-
278
- def test_building_the_associated_object_with_an_unrelated_type
279
- firm = DependentFirm.new
280
- assert_raise(ActiveRecord::SubclassNotFound) { firm.build_company(:type => "Account") }
281
- end
282
-
283
- def test_build_and_create_should_not_happen_within_scope
284
- pirate = pirates(:blackbeard)
285
- scope = pirate.association(:foo_bulb).scope.where_values_hash
286
-
287
- bulb = pirate.build_foo_bulb
288
- assert_not_equal scope, bulb.scope_after_initialize.where_values_hash
289
-
290
- bulb = pirate.create_foo_bulb
291
- assert_not_equal scope, bulb.scope_after_initialize.where_values_hash
292
-
293
- bulb = pirate.create_foo_bulb!
294
- assert_not_equal scope, bulb.scope_after_initialize.where_values_hash
295
- end
296
-
297
- def test_create_association
298
- firm = Firm.create(:name => "GlobalMegaCorp")
299
- account = firm.create_account(:credit_limit => 1000)
300
- assert_equal account, firm.reload.account
301
- end
302
-
303
- def test_create_association_with_bang
304
- firm = Firm.create(:name => "GlobalMegaCorp")
305
- account = firm.create_account!(:credit_limit => 1000)
306
- assert_equal account, firm.reload.account
307
- end
308
-
309
- def test_create_association_with_bang_failing
310
- firm = Firm.create(:name => "GlobalMegaCorp")
311
- assert_raise ActiveRecord::RecordInvalid do
312
- firm.create_account!
313
- end
314
- account = firm.account
315
- assert_not_nil account
316
- account.credit_limit = 5
317
- account.save
318
- assert_equal account, firm.reload.account
319
- end
320
-
321
- def test_create_with_inexistent_foreign_key_failing
322
- firm = Firm.create(name: 'GlobalMegaCorp')
323
-
324
- assert_raises(ActiveRecord::UnknownAttributeError) do
325
- firm.create_account_with_inexistent_foreign_key
326
- end
327
- end
328
-
329
- def test_reload_association
330
- odegy = companies(:odegy)
331
-
332
- assert_equal 53, odegy.account.credit_limit
333
- Account.where(id: odegy.account.id).update_all(credit_limit: 80)
334
- assert_equal 53, odegy.account.credit_limit
335
-
336
- assert_equal 80, odegy.reload_account.credit_limit
337
- end
338
-
339
- def test_build
340
- firm = Firm.new("name" => "GlobalMegaCorp")
341
- firm.save
342
-
343
- firm.account = account = Account.new("credit_limit" => 1000)
344
- assert_equal account, firm.account
345
- assert account.save
346
- assert_equal account, firm.account
347
- end
348
-
349
- def test_create
350
- firm = Firm.new("name" => "GlobalMegaCorp")
351
- firm.save
352
- firm.account = account = Account.create("credit_limit" => 1000)
353
- assert_equal account, firm.account
354
- end
355
-
356
- def test_create_before_save
357
- firm = Firm.new("name" => "GlobalMegaCorp")
358
- firm.account = account = Account.create("credit_limit" => 1000)
359
- assert_equal account, firm.account
360
- end
361
-
362
- def test_dependence_with_missing_association
363
- Account.destroy_all
364
- firm = Firm.find(1)
365
- assert_nil firm.account
366
- firm.destroy
367
- end
368
-
369
- def test_dependence_with_missing_association_and_nullify
370
- Account.destroy_all
371
- firm = DependentFirm.first
372
- assert_nil firm.account
373
- firm.destroy
374
- end
375
-
376
- def test_finding_with_interpolated_condition
377
- firm = Firm.first
378
- superior = firm.clients.create(:name => 'SuperiorCo')
379
- superior.rating = 10
380
- superior.save
381
- assert_equal 10, firm.clients_with_interpolated_conditions.first.rating
382
- end
383
-
384
- def test_assignment_before_child_saved
385
- firm = Firm.find(1)
386
- firm.account = a = Account.new("credit_limit" => 1000)
387
- assert a.persisted?
388
- assert_equal a, firm.account
389
- assert_equal a, firm.account
390
- firm.association(:account).reload
391
- assert_equal a, firm.account
392
- end
393
-
394
- def test_save_still_works_after_accessing_nil_has_one
395
- jp = Company.new :name => 'Jaded Pixel'
396
- jp.dummy_account.nil?
397
-
398
- assert_nothing_raised do
399
- jp.save!
400
- end
401
- end
402
-
403
- def test_cant_save_readonly_association
404
- assert_raise(ActiveRecord::ReadOnlyRecord) { companies(:first_firm).readonly_account.save! }
405
- assert companies(:first_firm).readonly_account.readonly?
406
- end
407
-
408
- def test_has_one_proxy_should_not_respond_to_private_methods
409
- assert_raise(NoMethodError) { accounts(:signals37).private_method }
410
- assert_raise(NoMethodError) { companies(:first_firm).account.private_method }
411
- end
412
-
413
- def test_has_one_proxy_should_respond_to_private_methods_via_send
414
- accounts(:signals37).send(:private_method)
415
- companies(:first_firm).account.send(:private_method)
416
- end
417
-
418
- def test_save_of_record_with_loaded_has_one
419
- @firm = companies(:first_firm)
420
- assert_not_nil @firm.account
421
-
422
- assert_nothing_raised do
423
- Firm.find(@firm.id).save!
424
- Firm.all.merge!(:includes => :account).find(@firm.id).save!
425
- end
426
-
427
- @firm.account.destroy
428
-
429
- assert_nothing_raised do
430
- Firm.find(@firm.id).save!
431
- Firm.all.merge!(:includes => :account).find(@firm.id).save!
432
- end
433
- end
434
-
435
- def test_build_respects_hash_condition
436
- account = companies(:first_firm).build_account_limit_500_with_hash_conditions
437
- assert account.save
438
- assert_equal 500, account.credit_limit
439
- end
440
-
441
- def test_create_respects_hash_condition
442
- account = companies(:first_firm).create_account_limit_500_with_hash_conditions
443
- assert account.persisted?
444
- assert_equal 500, account.credit_limit
445
- end
446
-
447
- 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')
449
- assert_equal new_account.firm_name, "Account"
450
- end
451
-
452
- def test_creation_failure_without_dependent_option
453
- pirate = pirates(:blackbeard)
454
- orig_ship = pirate.ship
455
-
456
- assert_equal ships(:black_pearl), orig_ship
457
- new_ship = pirate.create_ship
458
- assert_not_equal ships(:black_pearl), new_ship
459
- assert_equal new_ship, pirate.ship
460
- assert new_ship.new_record?
461
- assert_nil orig_ship.pirate_id
462
- assert !orig_ship.changed? # check it was saved
463
- end
464
-
465
- def test_creation_failure_with_dependent_option
466
- pirate = pirates(:blackbeard).becomes(DestructivePirate)
467
- orig_ship = pirate.dependent_ship
468
-
469
- new_ship = pirate.create_dependent_ship
470
- assert new_ship.new_record?
471
- assert orig_ship.destroyed?
472
- end
473
-
474
- def test_creation_failure_due_to_new_record_should_raise_error
475
- pirate = pirates(:redbeard)
476
- new_ship = Ship.new
477
-
478
- error = assert_raise(ActiveRecord::RecordNotSaved) do
479
- pirate.ship = new_ship
480
- end
481
-
482
- assert_equal "Failed to save the new associated ship.", error.message
483
- assert_nil pirate.ship
484
- assert_nil new_ship.pirate_id
485
- end
486
-
487
- def test_replacement_failure_due_to_existing_record_should_raise_error
488
- pirate = pirates(:blackbeard)
489
- pirate.ship.name = nil
490
-
491
- assert !pirate.ship.valid?
492
- error = assert_raise(ActiveRecord::RecordNotSaved) do
493
- pirate.ship = ships(:interceptor)
494
- end
495
-
496
- assert_equal ships(:black_pearl), pirate.ship
497
- assert_equal pirate.id, pirate.ship.pirate_id
498
- assert_equal "Failed to remove the existing associated ship. " +
499
- "The record failed to save after its foreign key was set to nil.", error.message
500
- end
501
-
502
- def test_replacement_failure_due_to_new_record_should_raise_error
503
- pirate = pirates(:blackbeard)
504
- new_ship = Ship.new
505
-
506
- error = assert_raise(ActiveRecord::RecordNotSaved) do
507
- pirate.ship = new_ship
508
- end
509
-
510
- assert_equal "Failed to save the new associated ship.", error.message
511
- assert_equal ships(:black_pearl), pirate.ship
512
- assert_equal pirate.id, pirate.ship.pirate_id
513
- assert_equal pirate.id, ships(:black_pearl).reload.pirate_id
514
- assert_nil new_ship.pirate_id
515
- end
516
-
517
- def test_association_keys_bypass_attribute_protection
518
- car = Car.create(:name => 'honda')
519
-
520
- bulb = car.build_bulb
521
- assert_equal car.id, bulb.car_id
522
-
523
- bulb = car.build_bulb :car_id => car.id + 1
524
- assert_equal car.id, bulb.car_id
525
-
526
- bulb = car.create_bulb
527
- assert_equal car.id, bulb.car_id
528
-
529
- bulb = car.create_bulb :car_id => car.id + 1
530
- assert_equal car.id, bulb.car_id
531
- end
532
-
533
- def test_association_protect_foreign_key
534
- pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?")
535
-
536
- ship = pirate.build_ship
537
- assert_equal pirate.id, ship.pirate_id
538
-
539
- ship = pirate.build_ship :pirate_id => pirate.id + 1
540
- assert_equal pirate.id, ship.pirate_id
541
-
542
- ship = pirate.create_ship
543
- assert_equal pirate.id, ship.pirate_id
544
-
545
- ship = pirate.create_ship :pirate_id => pirate.id + 1
546
- assert_equal pirate.id, ship.pirate_id
547
- end
548
-
549
- def test_build_with_block
550
- car = Car.create(:name => 'honda')
551
-
552
- bulb = car.build_bulb{ |b| b.color = 'Red' }
553
- assert_equal 'RED!', bulb.color
554
- end
555
-
556
- def test_create_with_block
557
- car = Car.create(:name => 'honda')
558
-
559
- bulb = car.create_bulb{ |b| b.color = 'Red' }
560
- assert_equal 'RED!', bulb.color
561
- end
562
-
563
- def test_create_bang_with_block
564
- car = Car.create(:name => 'honda')
565
-
566
- bulb = car.create_bulb!{ |b| b.color = 'Red' }
567
- assert_equal 'RED!', bulb.color
568
- end
569
-
570
- def test_association_attributes_are_available_to_after_initialize
571
- car = Car.create(:name => 'honda')
572
- bulb = car.create_bulb
573
-
574
- assert_equal car.id, bulb.attributes_after_initialize['car_id']
575
- end
576
-
577
- def test_has_one_transaction
578
- company = companies(:first_firm)
579
- account = Account.find(1)
580
-
581
- company.account # force loading
582
- assert_no_queries { company.account = account }
583
-
584
- company.account = nil
585
- assert_no_queries { company.account = nil }
586
- account = Account.find(2)
587
- assert_queries { company.account = account }
588
-
589
- assert_no_queries { Firm.new.account = account }
590
- end
591
-
592
- def test_has_one_assignment_dont_trigger_save_on_change_of_same_object
593
- pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?")
594
- ship = pirate.build_ship(name: 'old name')
595
- ship.save!
596
-
597
- ship.name = 'new name'
598
- assert ship.changed?
599
- assert_queries(1) do
600
- # One query for updating name, not triggering query for updating pirate_id
601
- pirate.ship = ship
602
- end
603
-
604
- assert_equal 'new name', pirate.ship.reload.name
605
- end
606
-
607
- def test_has_one_assignment_triggers_save_on_change_on_replacing_object
608
- pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?")
609
- ship = pirate.build_ship(name: 'old name')
610
- ship.save!
611
-
612
- new_ship = Ship.create(name: 'new name')
613
- assert_queries(2) do
614
- # One query for updating name and second query for updating pirate_id
615
- pirate.ship = new_ship
616
- end
617
-
618
- assert_equal 'new name', pirate.ship.reload.name
619
- end
620
-
621
- 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')
624
-
625
- author.post = post
626
- author.save
627
- author.reload
628
-
629
- assert_not_nil author.post
630
- assert_equal author.post, post
631
- end
632
-
633
- def test_has_one_loading_for_new_record
634
- post = Post.create!(author_id: 42, title: 'foo', body: 'bar')
635
- author = Author.new(id: 42)
636
- assert_equal post, author.post
637
- end
638
-
639
- def test_has_one_relationship_cannot_have_a_counter_cache
640
- assert_raise(ArgumentError) do
641
- Class.new(ActiveRecord::Base) do
642
- has_one :thing, counter_cache: true
643
- end
644
- end
645
- end
646
-
647
- def test_with_polymorphic_has_one_with_custom_columns_name
648
- post = Post.create! :title => 'foo', :body => 'bar'
649
- image = Image.create!
650
-
651
- post.main_image = image
652
- post.reload
653
-
654
- assert_equal image, post.main_image
655
- end
656
-
657
- test 'dangerous association name raises ArgumentError' do
658
- [:errors, 'errors', :save, 'save'].each do |name|
659
- assert_raises(ArgumentError, "Association #{name} should not be allowed") do
660
- Class.new(ActiveRecord::Base) do
661
- has_one name
662
- end
663
- end
664
- end
665
- end
666
-
667
- def test_association_force_reload_with_only_true_is_deprecated
668
- firm = Firm.find(1)
669
-
670
- assert_deprecated("call `reload_account` instead") { firm.account(true) }
671
- end
672
-
673
- class SpecialBook < ActiveRecord::Base
674
- self.table_name = "books"
675
- belongs_to :author, class_name: "SpecialAuthor"
676
- has_one :subscription, class_name: "SpecialSupscription", foreign_key: "subscriber_id"
677
- end
678
-
679
- class SpecialAuthor < ActiveRecord::Base
680
- self.table_name = 'authors'
681
- has_one :book, class_name: 'SpecialBook', foreign_key: 'author_id'
682
- end
683
-
684
- class SpecialSupscription < ActiveRecord::Base
685
- self.table_name = "subscriptions"
686
- belongs_to :book, class_name: "SpecialBook"
687
- end
688
-
689
- def test_assocation_enum_works_properly
690
- author = SpecialAuthor.create!(name: 'Test')
691
- book = SpecialBook.create!(status: 'published')
692
- author.book = book
693
-
694
- refute_equal 0, SpecialAuthor.joins(:book).where(books: { status: 'published' } ).count
695
- end
696
-
697
- def test_assocation_enum_works_properly_with_nested_join
698
- author = SpecialAuthor.create!(name: "Test")
699
- book = SpecialBook.create!(status: "published")
700
- author.book = book
701
-
702
- where_clause = { books: { subscriptions: { subscriber_id: nil } } }
703
- assert_nothing_raised do
704
- SpecialAuthor.joins(book: :subscription).where.not(where_clause)
705
- end
706
- end
707
- end
1
+ 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'
13
+
14
+ class HasOneAssociationsTest < ActiveRecord::TestCase
15
+ self.use_transactional_tests = false unless supports_savepoints?
16
+ fixtures :accounts, :companies, :developers, :projects, :developers_projects, :ships, :pirates
17
+
18
+ def setup
19
+ Account.destroyed_account_ids.clear
20
+ end
21
+
22
+ 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
25
+ end
26
+
27
+ 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'
32
+ end
33
+
34
+ def test_has_one_cache_nils
35
+ firm = companies(:another_firm)
36
+ assert_queries(1) { assert_nil firm.account }
37
+ assert_queries(0) { assert_nil firm.account }
38
+
39
+ firms = Firm.all.merge!(:includes => :account).to_a
40
+ assert_queries(0) { firms.each(&:account) }
41
+ end
42
+
43
+ def test_with_select
44
+ 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
46
+ end
47
+
48
+ def test_finding_using_primary_key
49
+ firm = companies(:first_firm)
50
+ assert_equal Account.find_by_firm_id(firm.id), firm.account
51
+ firm.firm_id = companies(:rails_core).id
52
+ assert_equal accounts(:rails_core_account), firm.account_using_primary_key
53
+ end
54
+
55
+ def test_update_with_foreign_and_primary_keys
56
+ firm = companies(:first_firm)
57
+ account = firm.account_using_foreign_and_primary_keys
58
+ assert_equal Account.find_by_firm_name(firm.name), account
59
+ firm.save
60
+ firm.reload
61
+ assert_equal account, firm.account_using_foreign_and_primary_keys
62
+ end
63
+
64
+ def test_can_marshal_has_one_association_with_nil_target
65
+ firm = Firm.new
66
+ assert_nothing_raised do
67
+ assert_equal firm.attributes, Marshal.load(Marshal.dump(firm)).attributes
68
+ end
69
+
70
+ firm.account
71
+ assert_nothing_raised do
72
+ assert_equal firm.attributes, Marshal.load(Marshal.dump(firm)).attributes
73
+ end
74
+ end
75
+
76
+ def test_proxy_assignment
77
+ company = companies(:first_firm)
78
+ assert_nothing_raised { company.account = company.account }
79
+ end
80
+
81
+ def test_type_mismatch
82
+ assert_raise(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = 1 }
83
+ assert_raise(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = Project.find(1) }
84
+ end
85
+
86
+ def test_natural_assignment
87
+ apple = Firm.create("name" => "Apple")
88
+ citibank = Account.create("credit_limit" => 10)
89
+ apple.account = citibank
90
+ assert_equal apple.id, citibank.firm_id
91
+ end
92
+
93
+ def test_natural_assignment_to_nil
94
+ old_account_id = companies(:first_firm).account.id
95
+ companies(:first_firm).account = nil
96
+ companies(:first_firm).save
97
+ assert_nil companies(:first_firm).account
98
+ # account is dependent, therefore is destroyed when reference to owner is lost
99
+ assert_raise(ActiveRecord::RecordNotFound) { Account.find(old_account_id) }
100
+ end
101
+
102
+ def test_nullification_on_association_change
103
+ firm = companies(:rails_core)
104
+ old_account_id = firm.account.id
105
+ firm.account = Account.new(:credit_limit => 5)
106
+ # account is dependent with nullify, therefore its firm_id should be nil
107
+ assert_nil Account.find(old_account_id).firm_id
108
+ end
109
+
110
+ def test_nullification_on_destroyed_association
111
+ developer = Developer.create!(name: "Someone")
112
+ ship = Ship.create!(name: "Planet Caravan", developer: developer)
113
+ ship.destroy
114
+ assert !ship.persisted?
115
+ assert !developer.persisted?
116
+ end
117
+
118
+ def test_natural_assignment_to_nil_after_destroy
119
+ firm = companies(:rails_core)
120
+ old_account_id = firm.account.id
121
+ firm.account.destroy
122
+ firm.account = nil
123
+ assert_nil companies(:rails_core).account
124
+ assert_raise(ActiveRecord::RecordNotFound) { Account.find(old_account_id) }
125
+ end
126
+
127
+ def test_association_change_calls_delete
128
+ companies(:first_firm).deletable_account = Account.new(:credit_limit => 5)
129
+ assert_equal [], Account.destroyed_account_ids[companies(:first_firm).id]
130
+ end
131
+
132
+ def test_association_change_calls_destroy
133
+ companies(:first_firm).account = Account.new(:credit_limit => 5)
134
+ assert_equal [companies(:first_firm).id], Account.destroyed_account_ids[companies(:first_firm).id]
135
+ end
136
+
137
+ def test_natural_assignment_to_already_associated_record
138
+ company = companies(:first_firm)
139
+ account = accounts(:signals37)
140
+ assert_equal company.account, account
141
+ company.account = account
142
+ company.reload
143
+ account.reload
144
+ assert_equal company.account, account
145
+ end
146
+
147
+ def test_dependence
148
+ num_accounts = Account.count
149
+
150
+ firm = Firm.find(1)
151
+ assert_not_nil firm.account
152
+ account_id = firm.account.id
153
+ assert_equal [], Account.destroyed_account_ids[firm.id]
154
+
155
+ firm.destroy
156
+ assert_equal num_accounts - 1, Account.count
157
+ assert_equal [account_id], Account.destroyed_account_ids[firm.id]
158
+ end
159
+
160
+ def test_exclusive_dependence
161
+ num_accounts = Account.count
162
+
163
+ firm = ExclusivelyDependentFirm.find(9)
164
+ assert_not_nil firm.account
165
+ assert_equal [], Account.destroyed_account_ids[firm.id]
166
+
167
+ firm.destroy
168
+ assert_equal num_accounts - 1, Account.count
169
+ assert_equal [], Account.destroyed_account_ids[firm.id]
170
+ end
171
+
172
+ def test_dependence_with_nil_associate
173
+ firm = DependentFirm.new(:name => 'nullify')
174
+ firm.save!
175
+ assert_nothing_raised { firm.destroy }
176
+ end
177
+
178
+ 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')
194
+ firm.create_account(credit_limit: 10)
195
+
196
+ assert_not_nil firm.account
197
+
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!
206
+ end
207
+
208
+ def test_restrict_with_error
209
+ firm = RestrictedWithErrorFirm.create!(:name => 'restrict')
210
+ firm.create_account(:credit_limit => 10)
211
+
212
+ assert_not_nil firm.account
213
+
214
+ firm.destroy
215
+
216
+ assert !firm.errors.empty?
217
+ 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?
220
+ end
221
+
222
+ def test_restrict_with_error_with_locale
223
+ 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')
226
+ firm.create_account(credit_limit: 10)
227
+
228
+ assert_not_nil firm.account
229
+
230
+ firm.destroy
231
+
232
+ assert !firm.errors.empty?
233
+ 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?
236
+ ensure
237
+ I18n.backend.reload!
238
+ end
239
+
240
+ def test_successful_build_association
241
+ firm = Firm.new("name" => "GlobalMegaCorp")
242
+ firm.save
243
+
244
+ account = firm.build_account("credit_limit" => 1000)
245
+ assert account.save
246
+ assert_equal account, firm.account
247
+ end
248
+
249
+ def test_build_association_dont_create_transaction
250
+ assert_no_queries(ignore_none: false) {
251
+ Firm.new.build_account
252
+ }
253
+ end
254
+
255
+ def test_building_the_associated_object_with_implicit_sti_base_class
256
+ firm = DependentFirm.new
257
+ company = firm.build_company
258
+ assert_kind_of Company, company, "Expected #{company.class} to be a Company"
259
+ end
260
+
261
+ def test_building_the_associated_object_with_explicit_sti_base_class
262
+ firm = DependentFirm.new
263
+ company = firm.build_company(:type => "Company")
264
+ assert_kind_of Company, company, "Expected #{company.class} to be a Company"
265
+ end
266
+
267
+ def test_building_the_associated_object_with_sti_subclass
268
+ firm = DependentFirm.new
269
+ company = firm.build_company(:type => "Client")
270
+ assert_kind_of Client, company, "Expected #{company.class} to be a Client"
271
+ end
272
+
273
+ def test_building_the_associated_object_with_an_invalid_type
274
+ firm = DependentFirm.new
275
+ assert_raise(ActiveRecord::SubclassNotFound) { firm.build_company(:type => "Invalid") }
276
+ end
277
+
278
+ def test_building_the_associated_object_with_an_unrelated_type
279
+ firm = DependentFirm.new
280
+ assert_raise(ActiveRecord::SubclassNotFound) { firm.build_company(:type => "Account") }
281
+ end
282
+
283
+ def test_build_and_create_should_not_happen_within_scope
284
+ pirate = pirates(:blackbeard)
285
+ scope = pirate.association(:foo_bulb).scope.where_values_hash
286
+
287
+ bulb = pirate.build_foo_bulb
288
+ assert_not_equal scope, bulb.scope_after_initialize.where_values_hash
289
+
290
+ bulb = pirate.create_foo_bulb
291
+ assert_not_equal scope, bulb.scope_after_initialize.where_values_hash
292
+
293
+ bulb = pirate.create_foo_bulb!
294
+ assert_not_equal scope, bulb.scope_after_initialize.where_values_hash
295
+ end
296
+
297
+ def test_create_association
298
+ firm = Firm.create(:name => "GlobalMegaCorp")
299
+ account = firm.create_account(:credit_limit => 1000)
300
+ assert_equal account, firm.reload.account
301
+ end
302
+
303
+ def test_create_association_with_bang
304
+ firm = Firm.create(:name => "GlobalMegaCorp")
305
+ account = firm.create_account!(:credit_limit => 1000)
306
+ assert_equal account, firm.reload.account
307
+ end
308
+
309
+ def test_create_association_with_bang_failing
310
+ firm = Firm.create(:name => "GlobalMegaCorp")
311
+ assert_raise ActiveRecord::RecordInvalid do
312
+ firm.create_account!
313
+ end
314
+ account = firm.account
315
+ assert_not_nil account
316
+ account.credit_limit = 5
317
+ account.save
318
+ assert_equal account, firm.reload.account
319
+ end
320
+
321
+ def test_create_with_inexistent_foreign_key_failing
322
+ firm = Firm.create(name: 'GlobalMegaCorp')
323
+
324
+ assert_raises(ActiveRecord::UnknownAttributeError) do
325
+ firm.create_account_with_inexistent_foreign_key
326
+ end
327
+ end
328
+
329
+ def test_reload_association
330
+ odegy = companies(:odegy)
331
+
332
+ assert_equal 53, odegy.account.credit_limit
333
+ Account.where(id: odegy.account.id).update_all(credit_limit: 80)
334
+ assert_equal 53, odegy.account.credit_limit
335
+
336
+ assert_equal 80, odegy.reload_account.credit_limit
337
+ end
338
+
339
+ def test_build
340
+ firm = Firm.new("name" => "GlobalMegaCorp")
341
+ firm.save
342
+
343
+ firm.account = account = Account.new("credit_limit" => 1000)
344
+ assert_equal account, firm.account
345
+ assert account.save
346
+ assert_equal account, firm.account
347
+ end
348
+
349
+ def test_create
350
+ firm = Firm.new("name" => "GlobalMegaCorp")
351
+ firm.save
352
+ firm.account = account = Account.create("credit_limit" => 1000)
353
+ assert_equal account, firm.account
354
+ end
355
+
356
+ def test_create_before_save
357
+ firm = Firm.new("name" => "GlobalMegaCorp")
358
+ firm.account = account = Account.create("credit_limit" => 1000)
359
+ assert_equal account, firm.account
360
+ end
361
+
362
+ def test_dependence_with_missing_association
363
+ Account.destroy_all
364
+ firm = Firm.find(1)
365
+ assert_nil firm.account
366
+ firm.destroy
367
+ end
368
+
369
+ def test_dependence_with_missing_association_and_nullify
370
+ Account.destroy_all
371
+ firm = DependentFirm.first
372
+ assert_nil firm.account
373
+ firm.destroy
374
+ end
375
+
376
+ def test_finding_with_interpolated_condition
377
+ firm = Firm.first
378
+ superior = firm.clients.create(:name => 'SuperiorCo')
379
+ superior.rating = 10
380
+ superior.save
381
+ assert_equal 10, firm.clients_with_interpolated_conditions.first.rating
382
+ end
383
+
384
+ def test_assignment_before_child_saved
385
+ firm = Firm.find(1)
386
+ firm.account = a = Account.new("credit_limit" => 1000)
387
+ assert a.persisted?
388
+ assert_equal a, firm.account
389
+ assert_equal a, firm.account
390
+ firm.association(:account).reload
391
+ assert_equal a, firm.account
392
+ end
393
+
394
+ def test_save_still_works_after_accessing_nil_has_one
395
+ jp = Company.new :name => 'Jaded Pixel'
396
+ jp.dummy_account.nil?
397
+
398
+ assert_nothing_raised do
399
+ jp.save!
400
+ end
401
+ end
402
+
403
+ def test_cant_save_readonly_association
404
+ assert_raise(ActiveRecord::ReadOnlyRecord) { companies(:first_firm).readonly_account.save! }
405
+ assert companies(:first_firm).readonly_account.readonly?
406
+ end
407
+
408
+ def test_has_one_proxy_should_not_respond_to_private_methods
409
+ assert_raise(NoMethodError) { accounts(:signals37).private_method }
410
+ assert_raise(NoMethodError) { companies(:first_firm).account.private_method }
411
+ end
412
+
413
+ def test_has_one_proxy_should_respond_to_private_methods_via_send
414
+ accounts(:signals37).send(:private_method)
415
+ companies(:first_firm).account.send(:private_method)
416
+ end
417
+
418
+ def test_save_of_record_with_loaded_has_one
419
+ @firm = companies(:first_firm)
420
+ assert_not_nil @firm.account
421
+
422
+ assert_nothing_raised do
423
+ Firm.find(@firm.id).save!
424
+ Firm.all.merge!(:includes => :account).find(@firm.id).save!
425
+ end
426
+
427
+ @firm.account.destroy
428
+
429
+ assert_nothing_raised do
430
+ Firm.find(@firm.id).save!
431
+ Firm.all.merge!(:includes => :account).find(@firm.id).save!
432
+ end
433
+ end
434
+
435
+ def test_build_respects_hash_condition
436
+ account = companies(:first_firm).build_account_limit_500_with_hash_conditions
437
+ assert account.save
438
+ assert_equal 500, account.credit_limit
439
+ end
440
+
441
+ def test_create_respects_hash_condition
442
+ account = companies(:first_firm).create_account_limit_500_with_hash_conditions
443
+ assert account.persisted?
444
+ assert_equal 500, account.credit_limit
445
+ end
446
+
447
+ 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')
449
+ assert_equal new_account.firm_name, "Account"
450
+ end
451
+
452
+ def test_creation_failure_without_dependent_option
453
+ pirate = pirates(:blackbeard)
454
+ orig_ship = pirate.ship
455
+
456
+ assert_equal ships(:black_pearl), orig_ship
457
+ new_ship = pirate.create_ship
458
+ assert_not_equal ships(:black_pearl), new_ship
459
+ assert_equal new_ship, pirate.ship
460
+ assert new_ship.new_record?
461
+ assert_nil orig_ship.pirate_id
462
+ assert !orig_ship.changed? # check it was saved
463
+ end
464
+
465
+ def test_creation_failure_with_dependent_option
466
+ pirate = pirates(:blackbeard).becomes(DestructivePirate)
467
+ orig_ship = pirate.dependent_ship
468
+
469
+ new_ship = pirate.create_dependent_ship
470
+ assert new_ship.new_record?
471
+ assert orig_ship.destroyed?
472
+ end
473
+
474
+ def test_creation_failure_due_to_new_record_should_raise_error
475
+ pirate = pirates(:redbeard)
476
+ new_ship = Ship.new
477
+
478
+ error = assert_raise(ActiveRecord::RecordNotSaved) do
479
+ pirate.ship = new_ship
480
+ end
481
+
482
+ assert_equal "Failed to save the new associated ship.", error.message
483
+ assert_nil pirate.ship
484
+ assert_nil new_ship.pirate_id
485
+ end
486
+
487
+ def test_replacement_failure_due_to_existing_record_should_raise_error
488
+ pirate = pirates(:blackbeard)
489
+ pirate.ship.name = nil
490
+
491
+ assert !pirate.ship.valid?
492
+ error = assert_raise(ActiveRecord::RecordNotSaved) do
493
+ pirate.ship = ships(:interceptor)
494
+ end
495
+
496
+ assert_equal ships(:black_pearl), pirate.ship
497
+ assert_equal pirate.id, pirate.ship.pirate_id
498
+ assert_equal "Failed to remove the existing associated ship. " +
499
+ "The record failed to save after its foreign key was set to nil.", error.message
500
+ end
501
+
502
+ def test_replacement_failure_due_to_new_record_should_raise_error
503
+ pirate = pirates(:blackbeard)
504
+ new_ship = Ship.new
505
+
506
+ error = assert_raise(ActiveRecord::RecordNotSaved) do
507
+ pirate.ship = new_ship
508
+ end
509
+
510
+ assert_equal "Failed to save the new associated ship.", error.message
511
+ assert_equal ships(:black_pearl), pirate.ship
512
+ assert_equal pirate.id, pirate.ship.pirate_id
513
+ assert_equal pirate.id, ships(:black_pearl).reload.pirate_id
514
+ assert_nil new_ship.pirate_id
515
+ end
516
+
517
+ def test_association_keys_bypass_attribute_protection
518
+ car = Car.create(:name => 'honda')
519
+
520
+ bulb = car.build_bulb
521
+ assert_equal car.id, bulb.car_id
522
+
523
+ bulb = car.build_bulb :car_id => car.id + 1
524
+ assert_equal car.id, bulb.car_id
525
+
526
+ bulb = car.create_bulb
527
+ assert_equal car.id, bulb.car_id
528
+
529
+ bulb = car.create_bulb :car_id => car.id + 1
530
+ assert_equal car.id, bulb.car_id
531
+ end
532
+
533
+ def test_association_protect_foreign_key
534
+ pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?")
535
+
536
+ ship = pirate.build_ship
537
+ assert_equal pirate.id, ship.pirate_id
538
+
539
+ ship = pirate.build_ship :pirate_id => pirate.id + 1
540
+ assert_equal pirate.id, ship.pirate_id
541
+
542
+ ship = pirate.create_ship
543
+ assert_equal pirate.id, ship.pirate_id
544
+
545
+ ship = pirate.create_ship :pirate_id => pirate.id + 1
546
+ assert_equal pirate.id, ship.pirate_id
547
+ end
548
+
549
+ def test_build_with_block
550
+ car = Car.create(:name => 'honda')
551
+
552
+ bulb = car.build_bulb{ |b| b.color = 'Red' }
553
+ assert_equal 'RED!', bulb.color
554
+ end
555
+
556
+ def test_create_with_block
557
+ car = Car.create(:name => 'honda')
558
+
559
+ bulb = car.create_bulb{ |b| b.color = 'Red' }
560
+ assert_equal 'RED!', bulb.color
561
+ end
562
+
563
+ def test_create_bang_with_block
564
+ car = Car.create(:name => 'honda')
565
+
566
+ bulb = car.create_bulb!{ |b| b.color = 'Red' }
567
+ assert_equal 'RED!', bulb.color
568
+ end
569
+
570
+ def test_association_attributes_are_available_to_after_initialize
571
+ car = Car.create(:name => 'honda')
572
+ bulb = car.create_bulb
573
+
574
+ assert_equal car.id, bulb.attributes_after_initialize['car_id']
575
+ end
576
+
577
+ def test_has_one_transaction
578
+ company = companies(:first_firm)
579
+ account = Account.find(1)
580
+
581
+ company.account # force loading
582
+ assert_no_queries { company.account = account }
583
+
584
+ company.account = nil
585
+ assert_no_queries { company.account = nil }
586
+ account = Account.find(2)
587
+ assert_queries { company.account = account }
588
+
589
+ assert_no_queries { Firm.new.account = account }
590
+ end
591
+
592
+ def test_has_one_assignment_dont_trigger_save_on_change_of_same_object
593
+ pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?")
594
+ ship = pirate.build_ship(name: 'old name')
595
+ ship.save!
596
+
597
+ ship.name = 'new name'
598
+ assert ship.changed?
599
+ assert_queries(1) do
600
+ # One query for updating name, not triggering query for updating pirate_id
601
+ pirate.ship = ship
602
+ end
603
+
604
+ assert_equal 'new name', pirate.ship.reload.name
605
+ end
606
+
607
+ def test_has_one_assignment_triggers_save_on_change_on_replacing_object
608
+ pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?")
609
+ ship = pirate.build_ship(name: 'old name')
610
+ ship.save!
611
+
612
+ new_ship = Ship.create(name: 'new name')
613
+ assert_queries(2) do
614
+ # One query for updating name and second query for updating pirate_id
615
+ pirate.ship = new_ship
616
+ end
617
+
618
+ assert_equal 'new name', pirate.ship.reload.name
619
+ end
620
+
621
+ 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')
624
+
625
+ author.post = post
626
+ author.save
627
+ author.reload
628
+
629
+ assert_not_nil author.post
630
+ assert_equal author.post, post
631
+ end
632
+
633
+ def test_has_one_loading_for_new_record
634
+ post = Post.create!(author_id: 42, title: 'foo', body: 'bar')
635
+ author = Author.new(id: 42)
636
+ assert_equal post, author.post
637
+ end
638
+
639
+ def test_has_one_relationship_cannot_have_a_counter_cache
640
+ assert_raise(ArgumentError) do
641
+ Class.new(ActiveRecord::Base) do
642
+ has_one :thing, counter_cache: true
643
+ end
644
+ end
645
+ end
646
+
647
+ def test_with_polymorphic_has_one_with_custom_columns_name
648
+ post = Post.create! :title => 'foo', :body => 'bar'
649
+ image = Image.create!
650
+
651
+ post.main_image = image
652
+ post.reload
653
+
654
+ assert_equal image, post.main_image
655
+ end
656
+
657
+ test 'dangerous association name raises ArgumentError' do
658
+ [:errors, 'errors', :save, 'save'].each do |name|
659
+ assert_raises(ArgumentError, "Association #{name} should not be allowed") do
660
+ Class.new(ActiveRecord::Base) do
661
+ has_one name
662
+ end
663
+ end
664
+ end
665
+ end
666
+
667
+ def test_association_force_reload_with_only_true_is_deprecated
668
+ firm = Firm.find(1)
669
+
670
+ assert_deprecated("call `reload_account` instead") { firm.account(true) }
671
+ end
672
+
673
+ class SpecialBook < ActiveRecord::Base
674
+ self.table_name = "books"
675
+ belongs_to :author, class_name: "SpecialAuthor"
676
+ has_one :subscription, class_name: "SpecialSupscription", foreign_key: "subscriber_id"
677
+ end
678
+
679
+ class SpecialAuthor < ActiveRecord::Base
680
+ self.table_name = 'authors'
681
+ has_one :book, class_name: 'SpecialBook', foreign_key: 'author_id'
682
+ end
683
+
684
+ class SpecialSupscription < ActiveRecord::Base
685
+ self.table_name = "subscriptions"
686
+ belongs_to :book, class_name: "SpecialBook"
687
+ end
688
+
689
+ def test_assocation_enum_works_properly
690
+ author = SpecialAuthor.create!(name: 'Test')
691
+ book = SpecialBook.create!(status: 'published')
692
+ author.book = book
693
+
694
+ refute_equal 0, SpecialAuthor.joins(:book).where(books: { status: 'published' } ).count
695
+ end
696
+
697
+ def test_assocation_enum_works_properly_with_nested_join
698
+ author = SpecialAuthor.create!(name: "Test")
699
+ book = SpecialBook.create!(status: "published")
700
+ author.book = book
701
+
702
+ where_clause = { books: { subscriptions: { subscriber_id: nil } } }
703
+ assert_nothing_raised do
704
+ SpecialAuthor.joins(book: :subscription).where.not(where_clause)
705
+ end
706
+ end
707
+ end