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