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,777 +1,777 @@
1
- require "cases/helper"
2
- require 'models/tag'
3
- require 'models/tagging'
4
- require 'models/post'
5
- require 'models/rating'
6
- require 'models/item'
7
- require 'models/comment'
8
- require 'models/author'
9
- require 'models/category'
10
- require 'models/categorization'
11
- require 'models/vertex'
12
- require 'models/edge'
13
- require 'models/book'
14
- require 'models/citation'
15
- require 'models/aircraft'
16
- require 'models/engine'
17
- require 'models/car'
18
-
19
- class AssociationsJoinModelTest < ActiveRecord::TestCase
20
- self.use_transactional_tests = false unless supports_savepoints?
21
-
22
- fixtures :posts, :authors, :categories, :categorizations, :comments, :tags, :taggings, :author_favorites, :vertices, :items, :books,
23
- # Reload edges table from fixtures as otherwise repeated test was failing
24
- :edges
25
-
26
- def test_has_many
27
- assert authors(:david).categories.include?(categories(:general))
28
- end
29
-
30
- def test_has_many_inherited
31
- assert authors(:mary).categories.include?(categories(:sti_test))
32
- end
33
-
34
- def test_inherited_has_many
35
- assert categories(:sti_test).authors.include?(authors(:mary))
36
- end
37
-
38
- def test_has_many_distinct_through_join_model
39
- assert_equal 2, authors(:mary).categorized_posts.size
40
- assert_equal 1, authors(:mary).unique_categorized_posts.size
41
- end
42
-
43
- def test_has_many_distinct_through_count
44
- author = authors(:mary)
45
- assert !authors(:mary).unique_categorized_posts.loaded?
46
- assert_queries(1) { assert_equal 1, author.unique_categorized_posts.count }
47
- assert_queries(1) { assert_equal 1, author.unique_categorized_posts.count(:title) }
48
- assert_queries(1) { assert_equal 0, author.unique_categorized_posts.where(title: nil).count(:title) }
49
- assert !authors(:mary).unique_categorized_posts.loaded?
50
- end
51
-
52
- def test_has_many_distinct_through_find
53
- assert_equal 1, authors(:mary).unique_categorized_posts.to_a.size
54
- end
55
-
56
- def test_polymorphic_has_many_going_through_join_model
57
- assert_equal tags(:general), tag = posts(:welcome).tags.first
58
- assert_no_queries do
59
- tag.tagging
60
- end
61
- end
62
-
63
- def test_count_polymorphic_has_many
64
- assert_equal 1, posts(:welcome).taggings.count
65
- assert_equal 1, posts(:welcome).tags.count
66
- end
67
-
68
- def test_polymorphic_has_many_going_through_join_model_with_find
69
- assert_equal tags(:general), tag = posts(:welcome).tags.first
70
- assert_no_queries do
71
- tag.tagging
72
- end
73
- end
74
-
75
- def test_polymorphic_has_many_going_through_join_model_with_include_on_source_reflection
76
- assert_equal tags(:general), tag = posts(:welcome).funky_tags.first
77
- assert_no_queries do
78
- tag.tagging
79
- end
80
- end
81
-
82
- def test_polymorphic_has_many_going_through_join_model_with_include_on_source_reflection_with_find
83
- assert_equal tags(:general), tag = posts(:welcome).funky_tags.first
84
- assert_no_queries do
85
- tag.tagging
86
- end
87
- end
88
-
89
- def test_polymorphic_has_many_going_through_join_model_with_custom_select_and_joins
90
- assert_equal tags(:general), tag = posts(:welcome).tags.add_joins_and_select.first
91
- assert_nothing_raised { tag.author_id }
92
- end
93
-
94
- def test_polymorphic_has_many_going_through_join_model_with_custom_foreign_key
95
- assert_equal tags(:misc), taggings(:welcome_general).super_tag
96
- assert_equal tags(:misc), posts(:welcome).super_tags.first
97
- end
98
-
99
- def test_polymorphic_has_many_create_model_with_inheritance_and_custom_base_class
100
- post = SubStiPost.create :title => 'SubStiPost', :body => 'SubStiPost body'
101
- assert_instance_of SubStiPost, post
102
-
103
- tagging = tags(:misc).taggings.create(:taggable => post)
104
- assert_equal "SubStiPost", tagging.taggable_type
105
- end
106
-
107
- def test_polymorphic_has_many_going_through_join_model_with_inheritance
108
- assert_equal tags(:general), posts(:thinking).tags.first
109
- end
110
-
111
- def test_polymorphic_has_many_going_through_join_model_with_inheritance_with_custom_class_name
112
- assert_equal tags(:general), posts(:thinking).funky_tags.first
113
- end
114
-
115
- def test_polymorphic_has_many_create_model_with_inheritance
116
- post = posts(:thinking)
117
- assert_instance_of SpecialPost, post
118
-
119
- tagging = tags(:misc).taggings.create(:taggable => post)
120
- assert_equal "Post", tagging.taggable_type
121
- end
122
-
123
- def test_polymorphic_has_one_create_model_with_inheritance
124
- tagging = tags(:misc).create_tagging(:taggable => posts(:thinking))
125
- assert_equal "Post", tagging.taggable_type
126
- end
127
-
128
- def test_set_polymorphic_has_many
129
- tagging = tags(:misc).taggings.create
130
- posts(:thinking).taggings << tagging
131
- assert_equal "Post", tagging.taggable_type
132
- end
133
-
134
- def test_set_polymorphic_has_one
135
- tagging = tags(:misc).taggings.create
136
- posts(:thinking).tagging = tagging
137
-
138
- assert_equal "Post", tagging.taggable_type
139
- assert_equal posts(:thinking).id, tagging.taggable_id
140
- assert_equal posts(:thinking), tagging.taggable
141
- end
142
-
143
- def test_set_polymorphic_has_one_on_new_record
144
- tagging = tags(:misc).taggings.create
145
- post = Post.new :title => "foo", :body => "bar"
146
- post.tagging = tagging
147
- post.save!
148
-
149
- assert_equal "Post", tagging.taggable_type
150
- assert_equal post.id, tagging.taggable_id
151
- assert_equal post, tagging.taggable
152
- end
153
-
154
- def test_create_polymorphic_has_many_with_scope
155
- old_count = posts(:welcome).taggings.count
156
- tagging = posts(:welcome).taggings.create(:tag => tags(:misc))
157
- assert_equal "Post", tagging.taggable_type
158
- assert_equal old_count+1, posts(:welcome).taggings.count
159
- end
160
-
161
- def test_create_bang_polymorphic_with_has_many_scope
162
- old_count = posts(:welcome).taggings.count
163
- tagging = posts(:welcome).taggings.create!(:tag => tags(:misc))
164
- assert_equal "Post", tagging.taggable_type
165
- assert_equal old_count+1, posts(:welcome).taggings.count
166
- end
167
-
168
- def test_create_polymorphic_has_one_with_scope
169
- old_count = Tagging.count
170
- tagging = posts(:welcome).create_tagging(:tag => tags(:misc))
171
- assert_equal "Post", tagging.taggable_type
172
- assert_equal old_count+1, Tagging.count
173
- end
174
-
175
- def test_delete_polymorphic_has_many_with_delete_all
176
- assert_equal 1, posts(:welcome).taggings.count
177
- posts(:welcome).taggings.first.update_columns taggable_type: 'PostWithHasManyDeleteAll'
178
- post = find_post_with_dependency(1, :has_many, :taggings, :delete_all)
179
-
180
- old_count = Tagging.count
181
- post.destroy
182
- assert_equal old_count-1, Tagging.count
183
- assert_equal 0, posts(:welcome).taggings.count
184
- end
185
-
186
- def test_delete_polymorphic_has_many_with_destroy
187
- assert_equal 1, posts(:welcome).taggings.count
188
- posts(:welcome).taggings.first.update_columns taggable_type: 'PostWithHasManyDestroy'
189
- post = find_post_with_dependency(1, :has_many, :taggings, :destroy)
190
-
191
- old_count = Tagging.count
192
- post.destroy
193
- assert_equal old_count-1, Tagging.count
194
- assert_equal 0, posts(:welcome).taggings.count
195
- end
196
-
197
- def test_delete_polymorphic_has_many_with_nullify
198
- assert_equal 1, posts(:welcome).taggings.count
199
- posts(:welcome).taggings.first.update_columns taggable_type: 'PostWithHasManyNullify'
200
- post = find_post_with_dependency(1, :has_many, :taggings, :nullify)
201
-
202
- old_count = Tagging.count
203
- post.destroy
204
- assert_equal old_count, Tagging.count
205
- assert_equal 0, posts(:welcome).taggings.count
206
- end
207
-
208
- def test_delete_polymorphic_has_one_with_destroy
209
- assert posts(:welcome).tagging
210
- posts(:welcome).tagging.update_columns taggable_type: 'PostWithHasOneDestroy'
211
- post = find_post_with_dependency(1, :has_one, :tagging, :destroy)
212
-
213
- old_count = Tagging.count
214
- post.destroy
215
- assert_equal old_count-1, Tagging.count
216
- posts(:welcome).association(:tagging).reload
217
- assert_nil posts(:welcome).tagging
218
- end
219
-
220
- def test_delete_polymorphic_has_one_with_nullify
221
- assert posts(:welcome).tagging
222
- posts(:welcome).tagging.update_columns taggable_type: 'PostWithHasOneNullify'
223
- post = find_post_with_dependency(1, :has_one, :tagging, :nullify)
224
-
225
- old_count = Tagging.count
226
- post.destroy
227
- assert_equal old_count, Tagging.count
228
- posts(:welcome).association(:tagging).reload
229
- assert_nil posts(:welcome).tagging
230
- end
231
-
232
- def test_has_many_with_piggyback
233
- assert_equal "2", categories(:sti_test).authors_with_select.first.post_id.to_s
234
- end
235
-
236
- def test_create_through_has_many_with_piggyback
237
- category = categories(:sti_test)
238
- ernie = category.authors_with_select.create(:name => 'Ernie')
239
- assert_nothing_raised do
240
- assert_equal ernie, category.authors_with_select.detect {|a| a.name == 'Ernie'}
241
- end
242
- end
243
-
244
- def test_include_has_many_through
245
- posts = Post.all.merge!(:order => 'posts.id').to_a
246
- posts_with_authors = Post.all.merge!(:includes => :authors, :order => 'posts.id').to_a
247
- assert_equal posts.length, posts_with_authors.length
248
- posts.length.times do |i|
249
- assert_equal posts[i].authors.length, assert_no_queries { posts_with_authors[i].authors.length }
250
- end
251
- end
252
-
253
- def test_include_polymorphic_has_one
254
- post = Post.includes(:tagging).find posts(:welcome).id
255
- tagging = taggings(:welcome_general)
256
- assert_no_queries do
257
- assert_equal tagging, post.tagging
258
- end
259
- end
260
-
261
- def test_include_polymorphic_has_one_defined_in_abstract_parent
262
- item = Item.includes(:tagging).find items(:dvd).id
263
- tagging = taggings(:godfather)
264
- assert_no_queries do
265
- assert_equal tagging, item.tagging
266
- end
267
- end
268
-
269
- def test_include_polymorphic_has_many_through
270
- posts = Post.all.merge!(:order => 'posts.id').to_a
271
- posts_with_tags = Post.all.merge!(:includes => :tags, :order => 'posts.id').to_a
272
- assert_equal posts.length, posts_with_tags.length
273
- posts.length.times do |i|
274
- assert_equal posts[i].tags.length, assert_no_queries { posts_with_tags[i].tags.length }
275
- end
276
- end
277
-
278
- def test_include_polymorphic_has_many
279
- posts = Post.all.merge!(:order => 'posts.id').to_a
280
- posts_with_taggings = Post.all.merge!(:includes => :taggings, :order => 'posts.id').to_a
281
- assert_equal posts.length, posts_with_taggings.length
282
- posts.length.times do |i|
283
- assert_equal posts[i].taggings.length, assert_no_queries { posts_with_taggings[i].taggings.length }
284
- end
285
- end
286
-
287
- def test_has_many_find_all
288
- assert_equal [categories(:general)], authors(:david).categories.to_a
289
- end
290
-
291
- def test_has_many_find_first
292
- assert_equal categories(:general), authors(:david).categories.first
293
- end
294
-
295
- def test_has_many_with_hash_conditions
296
- assert_equal categories(:general), authors(:david).categories_like_general.first
297
- end
298
-
299
- def test_has_many_find_conditions
300
- assert_equal categories(:general), authors(:david).categories.where("categories.name = 'General'").first
301
- assert_nil authors(:david).categories.where("categories.name = 'Technology'").first
302
- end
303
-
304
- def test_has_many_array_methods_called_by_method_missing
305
- assert authors(:david).categories.any? { |category| category.name == 'General' }
306
- assert_nothing_raised { authors(:david).categories.sort }
307
- end
308
-
309
- def test_has_many_going_through_join_model_with_custom_foreign_key
310
- assert_equal [authors(:bob)], posts(:thinking).authors
311
- assert_equal [authors(:mary)], posts(:authorless).authors
312
- end
313
-
314
- def test_has_many_going_through_join_model_with_custom_primary_key
315
- assert_equal [authors(:david)], posts(:thinking).authors_using_author_id
316
- end
317
-
318
- def test_has_many_going_through_polymorphic_join_model_with_custom_primary_key
319
- assert_equal [tags(:general)], posts(:eager_other).tags_using_author_id
320
- end
321
-
322
- def test_has_many_through_with_custom_primary_key_on_belongs_to_source
323
- assert_equal [authors(:david), authors(:david)], posts(:thinking).author_using_custom_pk
324
- end
325
-
326
- def test_has_many_through_with_custom_primary_key_on_has_many_source
327
- assert_equal [authors(:david), authors(:bob)], posts(:thinking).authors_using_custom_pk.order('authors.id')
328
- end
329
-
330
- def test_belongs_to_polymorphic_with_counter_cache
331
- assert_equal 1, posts(:welcome)[:tags_count]
332
- tagging = posts(:welcome).taggings.create(:tag => tags(:general))
333
- assert_equal 2, posts(:welcome, :reload)[:tags_count]
334
- tagging.destroy
335
- assert_equal 1, posts(:welcome, :reload)[:tags_count]
336
- end
337
-
338
- def test_unavailable_through_reflection
339
- assert_raise(ActiveRecord::HasManyThroughAssociationNotFoundError) { authors(:david).nothings }
340
- end
341
-
342
- def test_has_many_through_join_model_with_conditions
343
- assert_equal [], posts(:welcome).invalid_taggings
344
- assert_equal [], posts(:welcome).invalid_tags
345
- end
346
-
347
- def test_has_many_polymorphic
348
- assert_raise ActiveRecord::HasManyThroughAssociationPolymorphicSourceError do
349
- tags(:general).taggables
350
- end
351
-
352
- assert_raise ActiveRecord::HasManyThroughAssociationPolymorphicThroughError do
353
- taggings(:welcome_general).things
354
- end
355
-
356
- assert_raise ActiveRecord::EagerLoadPolymorphicError do
357
- tags(:general).taggings.includes(:taggable).where('bogus_table.column = 1').references(:bogus_table).to_a
358
- end
359
- end
360
-
361
- def test_has_many_polymorphic_with_source_type
362
- # added sort by ID as otherwise Oracle select sometimes returned rows in different order
363
- assert_equal posts(:welcome, :thinking).sort_by(&:id), tags(:general).tagged_posts.sort_by(&:id)
364
- end
365
-
366
- def test_has_many_polymorphic_associations_merges_through_scope
367
- Tag.has_many :null_taggings, -> { none }, class_name: :Tagging
368
- Tag.has_many :null_tagged_posts, :through => :null_taggings, :source => 'taggable', :source_type => 'Post'
369
- assert_equal [], tags(:general).null_tagged_posts
370
- refute_equal [], tags(:general).tagged_posts
371
- end
372
-
373
- def test_eager_has_many_polymorphic_with_source_type
374
- tag_with_include = Tag.all.merge!(:includes => :tagged_posts).find(tags(:general).id)
375
- desired = posts(:welcome, :thinking)
376
- assert_no_queries do
377
- # added sort by ID as otherwise test using JRuby was failing as array elements were in different order
378
- assert_equal desired.sort_by(&:id), tag_with_include.tagged_posts.sort_by(&:id)
379
- end
380
- assert_equal 5, tag_with_include.taggings.length
381
- end
382
-
383
- def test_has_many_through_has_many_find_all
384
- assert_equal comments(:greetings), authors(:david).comments.order('comments.id').to_a.first
385
- end
386
-
387
- def test_has_many_through_has_many_find_all_with_custom_class
388
- assert_equal comments(:greetings), authors(:david).funky_comments.order('comments.id').to_a.first
389
- end
390
-
391
- def test_has_many_through_has_many_find_first
392
- assert_equal comments(:greetings), authors(:david).comments.order('comments.id').first
393
- end
394
-
395
- def test_has_many_through_has_many_find_conditions
396
- options = { :where => "comments.#{QUOTED_TYPE}='SpecialComment'", :order => 'comments.id' }
397
- assert_equal comments(:does_it_hurt), authors(:david).comments.merge(options).first
398
- end
399
-
400
- def test_has_many_through_has_many_find_by_id
401
- assert_equal comments(:more_greetings), authors(:david).comments.find(2)
402
- end
403
-
404
- def test_has_many_through_polymorphic_has_one
405
- assert_equal Tagging.find(1,2).sort_by(&:id), authors(:david).taggings_2
406
- end
407
-
408
- def test_has_many_through_polymorphic_has_many
409
- assert_equal taggings(:welcome_general, :thinking_general), authors(:david).taggings.distinct.sort_by(&:id)
410
- end
411
-
412
- def test_include_has_many_through_polymorphic_has_many
413
- author = Author.includes(:taggings).find authors(:david).id
414
- expected_taggings = taggings(:welcome_general, :thinking_general)
415
- assert_no_queries do
416
- assert_equal expected_taggings, author.taggings.distinct.sort_by(&:id)
417
- end
418
- end
419
-
420
- def test_eager_load_has_many_through_has_many
421
- author = Author.all.merge!(:where => ['name = ?', 'David'], :includes => :comments, :order => 'comments.id').first
422
- SpecialComment.new; VerySpecialComment.new
423
- assert_no_queries do
424
- assert_equal [1,2,3,5,6,7,8,9,10,12], author.comments.collect(&:id)
425
- end
426
- end
427
-
428
- def test_eager_load_has_many_through_has_many_with_conditions
429
- post = Post.all.merge!(:includes => :invalid_tags).first
430
- assert_no_queries do
431
- post.invalid_tags
432
- end
433
- end
434
-
435
- def test_eager_belongs_to_and_has_one_not_singularized
436
- assert_nothing_raised do
437
- Author.all.merge!(:includes => :author_address).first
438
- AuthorAddress.all.merge!(:includes => :author).first
439
- end
440
- end
441
-
442
- def test_self_referential_has_many_through
443
- assert_equal [authors(:mary)], authors(:david).favorite_authors
444
- assert_equal [], authors(:mary).favorite_authors
445
- end
446
-
447
- def test_add_to_self_referential_has_many_through
448
- new_author = Author.create(:name => "Bob")
449
- authors(:david).author_favorites.create :favorite_author => new_author
450
- assert_equal new_author, authors(:david).reload.favorite_authors.first
451
- end
452
-
453
- def test_has_many_through_uses_conditions_specified_on_the_has_many_association
454
- author = Author.first
455
- assert author.comments.present?
456
- assert author.nonexistent_comments.blank?
457
- end
458
-
459
- def test_has_many_through_uses_correct_attributes
460
- assert_nil posts(:thinking).tags.find_by_name("General").attributes["tag_id"]
461
- end
462
-
463
- def test_associating_unsaved_records_with_has_many_through
464
- saved_post = posts(:thinking)
465
- new_tag = Tag.new(:name => "new")
466
-
467
- saved_post.tags << new_tag
468
- assert new_tag.persisted? #consistent with habtm!
469
- assert saved_post.persisted?
470
- assert saved_post.tags.include?(new_tag)
471
-
472
- assert new_tag.persisted?
473
- assert saved_post.reload.tags.reload.include?(new_tag)
474
-
475
-
476
- new_post = Post.new(:title => "Association replacement works!", :body => "You best believe it.")
477
- saved_tag = tags(:general)
478
-
479
- new_post.tags << saved_tag
480
- assert !new_post.persisted?
481
- assert saved_tag.persisted?
482
- assert new_post.tags.include?(saved_tag)
483
-
484
- new_post.save!
485
- assert new_post.persisted?
486
- assert new_post.reload.tags.reload.include?(saved_tag)
487
-
488
- assert !posts(:thinking).tags.build.persisted?
489
- assert !posts(:thinking).tags.new.persisted?
490
- end
491
-
492
- def test_create_associate_when_adding_to_has_many_through
493
- count = posts(:thinking).tags.count
494
- push = Tag.create!(:name => 'pushme')
495
- post_thinking = posts(:thinking)
496
- assert_nothing_raised { post_thinking.tags << push }
497
- assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
498
- message = "Expected a Tag in tags collection, got #{wrong.class}.")
499
- assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
500
- message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
501
- assert_equal(count + 1, post_thinking.reload.tags.size)
502
- assert_equal(count + 1, post_thinking.tags.reload.size)
503
-
504
- assert_kind_of Tag, post_thinking.tags.create!(:name => 'foo')
505
- assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
506
- message = "Expected a Tag in tags collection, got #{wrong.class}.")
507
- assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
508
- message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
509
- assert_equal(count + 2, post_thinking.reload.tags.size)
510
- assert_equal(count + 2, post_thinking.tags.reload.size)
511
-
512
- assert_nothing_raised { post_thinking.tags.concat(Tag.create!(:name => 'abc'), Tag.create!(:name => 'def')) }
513
- assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
514
- message = "Expected a Tag in tags collection, got #{wrong.class}.")
515
- assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
516
- message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
517
- assert_equal(count + 4, post_thinking.reload.tags.size)
518
- assert_equal(count + 4, post_thinking.tags.reload.size)
519
-
520
- # Raises if the wrong reflection name is used to set the Edge belongs_to
521
- assert_nothing_raised { vertices(:vertex_1).sinks << vertices(:vertex_5) }
522
- end
523
-
524
- def test_add_to_join_table_with_no_id
525
- assert_nothing_raised { vertices(:vertex_1).sinks << vertices(:vertex_5) }
526
- end
527
-
528
- def test_has_many_through_collection_size_doesnt_load_target_if_not_loaded
529
- author = authors(:david)
530
- assert_equal 10, author.comments.size
531
- assert !author.comments.loaded?
532
- end
533
-
534
- def test_has_many_through_collection_size_uses_counter_cache_if_it_exists
535
- c = categories(:general)
536
- c.categorizations_count = 100
537
- assert_equal 100, c.categorizations.size
538
- assert !c.categorizations.loaded?
539
- end
540
-
541
- def test_adding_junk_to_has_many_through_should_raise_type_mismatch
542
- assert_raise(ActiveRecord::AssociationTypeMismatch) { posts(:thinking).tags << "Uhh what now?" }
543
- end
544
-
545
- def test_adding_to_has_many_through_should_return_self
546
- tags = posts(:thinking).tags
547
- assert_equal tags, posts(:thinking).tags.push(tags(:general))
548
- end
549
-
550
- def test_delete_associate_when_deleting_from_has_many_through_with_nonstandard_id
551
- count = books(:awdr).references.count
552
- references_before = books(:awdr).references
553
- book = Book.create!(:name => 'Getting Real')
554
- book_awdr = books(:awdr)
555
- book_awdr.references << book
556
- assert_equal(count + 1, book_awdr.references.reload.size)
557
-
558
- assert_nothing_raised { book_awdr.references.delete(book) }
559
- assert_equal(count, book_awdr.references.size)
560
- assert_equal(count, book_awdr.references.reload.size)
561
- assert_equal(references_before.sort, book_awdr.references.sort)
562
- end
563
-
564
- def test_delete_associate_when_deleting_from_has_many_through
565
- count = posts(:thinking).tags.count
566
- tags_before = posts(:thinking).tags.sort
567
- tag = Tag.create!(:name => 'doomed')
568
- post_thinking = posts(:thinking)
569
- post_thinking.tags << tag
570
- assert_equal(count + 1, post_thinking.taggings.reload.size)
571
- assert_equal(count + 1, post_thinking.reload.tags.reload.size)
572
- assert_not_equal(tags_before, post_thinking.tags.sort)
573
-
574
- assert_nothing_raised { post_thinking.tags.delete(tag) }
575
- assert_equal(count, post_thinking.tags.size)
576
- assert_equal(count, post_thinking.tags.reload.size)
577
- assert_equal(count, post_thinking.taggings.reload.size)
578
- assert_equal(tags_before, post_thinking.tags.sort)
579
- end
580
-
581
- def test_delete_associate_when_deleting_from_has_many_through_with_multiple_tags
582
- count = posts(:thinking).tags.count
583
- tags_before = posts(:thinking).tags.sort
584
- doomed = Tag.create!(:name => 'doomed')
585
- doomed2 = Tag.create!(:name => 'doomed2')
586
- quaked = Tag.create!(:name => 'quaked')
587
- post_thinking = posts(:thinking)
588
- post_thinking.tags << doomed << doomed2
589
- assert_equal(count + 2, post_thinking.reload.tags.reload.size)
590
-
591
- assert_nothing_raised { post_thinking.tags.delete(doomed, doomed2, quaked) }
592
- assert_equal(count, post_thinking.tags.size)
593
- assert_equal(count, post_thinking.tags.reload.size)
594
- assert_equal(tags_before, post_thinking.tags.sort)
595
- end
596
-
597
- def test_deleting_junk_from_has_many_through_should_raise_type_mismatch
598
- assert_raise(ActiveRecord::AssociationTypeMismatch) { posts(:thinking).tags.delete(Object.new) }
599
- end
600
-
601
- def test_deleting_by_integer_id_from_has_many_through
602
- post = posts(:thinking)
603
-
604
- assert_difference 'post.tags.count', -1 do
605
- assert_equal 1, post.tags.delete(1).size
606
- end
607
-
608
- assert_equal 0, post.tags.size
609
- end
610
-
611
- def test_deleting_by_string_id_from_has_many_through
612
- post = posts(:thinking)
613
-
614
- assert_difference 'post.tags.count', -1 do
615
- assert_equal 1, post.tags.delete('1').size
616
- end
617
-
618
- assert_equal 0, post.tags.size
619
- end
620
-
621
- def test_has_many_through_sum_uses_calculations
622
- assert_nothing_raised { authors(:david).comments.sum(:post_id) }
623
- end
624
-
625
- def test_calculations_on_has_many_through_should_disambiguate_fields
626
- assert_nothing_raised { authors(:david).categories.maximum(:id) }
627
- end
628
-
629
- def test_calculations_on_has_many_through_should_not_disambiguate_fields_unless_necessary
630
- assert_nothing_raised { authors(:david).categories.maximum("categories.id") }
631
- end
632
-
633
- def test_has_many_through_has_many_with_sti
634
- assert_equal [comments(:does_it_hurt)], authors(:david).special_post_comments
635
- end
636
-
637
- def test_distinct_has_many_through_should_retain_order
638
- comment_ids = authors(:david).comments.map(&:id)
639
- assert_equal comment_ids.sort, authors(:david).ordered_uniq_comments.map(&:id)
640
- assert_equal comment_ids.sort.reverse, authors(:david).ordered_uniq_comments_desc.map(&:id)
641
- end
642
-
643
- def test_polymorphic_has_many
644
- expected = taggings(:welcome_general)
645
- p = Post.all.merge!(:includes => :taggings).find(posts(:welcome).id)
646
- assert_no_queries {assert p.taggings.include?(expected)}
647
- assert posts(:welcome).taggings.include?(taggings(:welcome_general))
648
- end
649
-
650
- def test_polymorphic_has_one
651
- expected = posts(:welcome)
652
-
653
- tagging = Tagging.all.merge!(:includes => :taggable).find(taggings(:welcome_general).id)
654
- assert_no_queries { assert_equal expected, tagging.taggable}
655
- end
656
-
657
- def test_polymorphic_belongs_to
658
- p = Post.all.merge!(:includes => {:taggings => :taggable}).find(posts(:welcome).id)
659
- assert_no_queries {assert_equal posts(:welcome), p.taggings.first.taggable}
660
- end
661
-
662
- def test_preload_polymorphic_has_many_through
663
- posts = Post.all.merge!(:order => 'posts.id').to_a
664
- posts_with_tags = Post.all.merge!(:includes => :tags, :order => 'posts.id').to_a
665
- assert_equal posts.length, posts_with_tags.length
666
- posts.length.times do |i|
667
- assert_equal posts[i].tags.length, assert_no_queries { posts_with_tags[i].tags.length }
668
- end
669
- end
670
-
671
- def test_preload_polymorph_many_types
672
- taggings = Tagging.all.merge!(:includes => :taggable, :where => ['taggable_type != ?', 'FakeModel']).to_a
673
- assert_no_queries do
674
- taggings.first.taggable.id
675
- taggings[1].taggable.id
676
- end
677
-
678
- taggables = taggings.map(&:taggable)
679
- assert taggables.include?(items(:dvd))
680
- assert taggables.include?(posts(:welcome))
681
- end
682
-
683
- def test_preload_nil_polymorphic_belongs_to
684
- assert_nothing_raised do
685
- Tagging.all.merge!(:includes => :taggable, :where => ['taggable_type IS NULL']).to_a
686
- end
687
- end
688
-
689
- def test_preload_polymorphic_has_many
690
- posts = Post.all.merge!(:order => 'posts.id').to_a
691
- posts_with_taggings = Post.all.merge!(:includes => :taggings, :order => 'posts.id').to_a
692
- assert_equal posts.length, posts_with_taggings.length
693
- posts.length.times do |i|
694
- assert_equal posts[i].taggings.length, assert_no_queries { posts_with_taggings[i].taggings.length }
695
- end
696
- end
697
-
698
- def test_belongs_to_shared_parent
699
- comments = Comment.all.merge!(:includes => :post, :where => 'post_id = 1').to_a
700
- assert_no_queries do
701
- assert_equal comments.first.post, comments[1].post
702
- end
703
- end
704
-
705
- def test_has_many_through_include_uses_array_include_after_loaded
706
- david = authors(:david)
707
- david.categories.load_target
708
-
709
- category = david.categories.first
710
-
711
- assert_no_queries do
712
- assert david.categories.loaded?
713
- assert david.categories.include?(category)
714
- end
715
- end
716
-
717
- def test_has_many_through_include_checks_if_record_exists_if_target_not_loaded
718
- david = authors(:david)
719
- category = david.categories.first
720
-
721
- david.reload
722
- assert ! david.categories.loaded?
723
- assert_queries(1) do
724
- assert david.categories.include?(category)
725
- end
726
- assert ! david.categories.loaded?
727
- end
728
-
729
- def test_has_many_through_include_returns_false_for_non_matching_record_to_verify_scoping
730
- david = authors(:david)
731
- category = Category.create!(:name => 'Not Associated')
732
-
733
- assert ! david.categories.loaded?
734
- assert ! david.categories.include?(category)
735
- end
736
-
737
- def test_has_many_through_goes_through_all_sti_classes
738
- sub_sti_post = SubStiPost.create!(:title => 'test', :body => 'test', :author_id => 1)
739
- new_comment = sub_sti_post.comments.create(:body => 'test')
740
-
741
- assert_equal [9, 10, new_comment.id], authors(:david).sti_post_comments.map(&:id).sort
742
- end
743
-
744
- def test_has_many_with_pluralize_table_names_false
745
- aircraft = Aircraft.create!(:name => "Airbus 380")
746
- engine = Engine.create!(:car_id => aircraft.id)
747
- assert_equal aircraft.engines, [engine]
748
- end
749
-
750
- def test_proper_error_message_for_eager_load_and_includes_association_errors
751
- includes_error = assert_raises(ActiveRecord::ConfigurationError) {
752
- Post.includes(:nonexistent_relation).where(nonexistent_relation: {name: 'Rochester'}).find(1)
753
- }
754
- assert_equal("Can't join 'Post' to association named 'nonexistent_relation'; perhaps you misspelled it?", includes_error.message)
755
-
756
- eager_load_error = assert_raises(ActiveRecord::ConfigurationError) {
757
- Post.eager_load(:nonexistent_relation).where(nonexistent_relation: {name: 'Rochester'}).find(1)
758
- }
759
- assert_equal("Can't join 'Post' to association named 'nonexistent_relation'; perhaps you misspelled it?", eager_load_error.message)
760
-
761
- includes_and_eager_load_error = assert_raises(ActiveRecord::ConfigurationError) {
762
- Post.eager_load(:nonexistent_relation).includes(:nonexistent_relation).where(nonexistent_relation: {name: 'Rochester'}).find(1)
763
- }
764
- assert_equal("Can't join 'Post' to association named 'nonexistent_relation'; perhaps you misspelled it?", includes_and_eager_load_error.message)
765
- end
766
-
767
- private
768
- # create dynamic Post models to allow different dependency options
769
- def find_post_with_dependency(post_id, association, association_name, dependency)
770
- class_name = "PostWith#{association.to_s.classify}#{dependency.to_s.classify}"
771
- Post.find(post_id).update_columns type: class_name
772
- klass = Object.const_set(class_name, Class.new(ActiveRecord::Base))
773
- klass.table_name = 'posts'
774
- klass.send(association, association_name, :as => :taggable, :dependent => dependency)
775
- klass.find(post_id)
776
- end
777
- end
1
+ require "cases/helper"
2
+ require 'models/tag'
3
+ require 'models/tagging'
4
+ require 'models/post'
5
+ require 'models/rating'
6
+ require 'models/item'
7
+ require 'models/comment'
8
+ require 'models/author'
9
+ require 'models/category'
10
+ require 'models/categorization'
11
+ require 'models/vertex'
12
+ require 'models/edge'
13
+ require 'models/book'
14
+ require 'models/citation'
15
+ require 'models/aircraft'
16
+ require 'models/engine'
17
+ require 'models/car'
18
+
19
+ class AssociationsJoinModelTest < ActiveRecord::TestCase
20
+ self.use_transactional_tests = false unless supports_savepoints?
21
+
22
+ fixtures :posts, :authors, :categories, :categorizations, :comments, :tags, :taggings, :author_favorites, :vertices, :items, :books,
23
+ # Reload edges table from fixtures as otherwise repeated test was failing
24
+ :edges
25
+
26
+ def test_has_many
27
+ assert authors(:david).categories.include?(categories(:general))
28
+ end
29
+
30
+ def test_has_many_inherited
31
+ assert authors(:mary).categories.include?(categories(:sti_test))
32
+ end
33
+
34
+ def test_inherited_has_many
35
+ assert categories(:sti_test).authors.include?(authors(:mary))
36
+ end
37
+
38
+ def test_has_many_distinct_through_join_model
39
+ assert_equal 2, authors(:mary).categorized_posts.size
40
+ assert_equal 1, authors(:mary).unique_categorized_posts.size
41
+ end
42
+
43
+ def test_has_many_distinct_through_count
44
+ author = authors(:mary)
45
+ assert !authors(:mary).unique_categorized_posts.loaded?
46
+ assert_queries(1) { assert_equal 1, author.unique_categorized_posts.count }
47
+ assert_queries(1) { assert_equal 1, author.unique_categorized_posts.count(:title) }
48
+ assert_queries(1) { assert_equal 0, author.unique_categorized_posts.where(title: nil).count(:title) }
49
+ assert !authors(:mary).unique_categorized_posts.loaded?
50
+ end
51
+
52
+ def test_has_many_distinct_through_find
53
+ assert_equal 1, authors(:mary).unique_categorized_posts.to_a.size
54
+ end
55
+
56
+ def test_polymorphic_has_many_going_through_join_model
57
+ assert_equal tags(:general), tag = posts(:welcome).tags.first
58
+ assert_no_queries do
59
+ tag.tagging
60
+ end
61
+ end
62
+
63
+ def test_count_polymorphic_has_many
64
+ assert_equal 1, posts(:welcome).taggings.count
65
+ assert_equal 1, posts(:welcome).tags.count
66
+ end
67
+
68
+ def test_polymorphic_has_many_going_through_join_model_with_find
69
+ assert_equal tags(:general), tag = posts(:welcome).tags.first
70
+ assert_no_queries do
71
+ tag.tagging
72
+ end
73
+ end
74
+
75
+ def test_polymorphic_has_many_going_through_join_model_with_include_on_source_reflection
76
+ assert_equal tags(:general), tag = posts(:welcome).funky_tags.first
77
+ assert_no_queries do
78
+ tag.tagging
79
+ end
80
+ end
81
+
82
+ def test_polymorphic_has_many_going_through_join_model_with_include_on_source_reflection_with_find
83
+ assert_equal tags(:general), tag = posts(:welcome).funky_tags.first
84
+ assert_no_queries do
85
+ tag.tagging
86
+ end
87
+ end
88
+
89
+ def test_polymorphic_has_many_going_through_join_model_with_custom_select_and_joins
90
+ assert_equal tags(:general), tag = posts(:welcome).tags.add_joins_and_select.first
91
+ assert_nothing_raised { tag.author_id }
92
+ end
93
+
94
+ def test_polymorphic_has_many_going_through_join_model_with_custom_foreign_key
95
+ assert_equal tags(:misc), taggings(:welcome_general).super_tag
96
+ assert_equal tags(:misc), posts(:welcome).super_tags.first
97
+ end
98
+
99
+ def test_polymorphic_has_many_create_model_with_inheritance_and_custom_base_class
100
+ post = SubStiPost.create :title => 'SubStiPost', :body => 'SubStiPost body'
101
+ assert_instance_of SubStiPost, post
102
+
103
+ tagging = tags(:misc).taggings.create(:taggable => post)
104
+ assert_equal "SubStiPost", tagging.taggable_type
105
+ end
106
+
107
+ def test_polymorphic_has_many_going_through_join_model_with_inheritance
108
+ assert_equal tags(:general), posts(:thinking).tags.first
109
+ end
110
+
111
+ def test_polymorphic_has_many_going_through_join_model_with_inheritance_with_custom_class_name
112
+ assert_equal tags(:general), posts(:thinking).funky_tags.first
113
+ end
114
+
115
+ def test_polymorphic_has_many_create_model_with_inheritance
116
+ post = posts(:thinking)
117
+ assert_instance_of SpecialPost, post
118
+
119
+ tagging = tags(:misc).taggings.create(:taggable => post)
120
+ assert_equal "Post", tagging.taggable_type
121
+ end
122
+
123
+ def test_polymorphic_has_one_create_model_with_inheritance
124
+ tagging = tags(:misc).create_tagging(:taggable => posts(:thinking))
125
+ assert_equal "Post", tagging.taggable_type
126
+ end
127
+
128
+ def test_set_polymorphic_has_many
129
+ tagging = tags(:misc).taggings.create
130
+ posts(:thinking).taggings << tagging
131
+ assert_equal "Post", tagging.taggable_type
132
+ end
133
+
134
+ def test_set_polymorphic_has_one
135
+ tagging = tags(:misc).taggings.create
136
+ posts(:thinking).tagging = tagging
137
+
138
+ assert_equal "Post", tagging.taggable_type
139
+ assert_equal posts(:thinking).id, tagging.taggable_id
140
+ assert_equal posts(:thinking), tagging.taggable
141
+ end
142
+
143
+ def test_set_polymorphic_has_one_on_new_record
144
+ tagging = tags(:misc).taggings.create
145
+ post = Post.new :title => "foo", :body => "bar"
146
+ post.tagging = tagging
147
+ post.save!
148
+
149
+ assert_equal "Post", tagging.taggable_type
150
+ assert_equal post.id, tagging.taggable_id
151
+ assert_equal post, tagging.taggable
152
+ end
153
+
154
+ def test_create_polymorphic_has_many_with_scope
155
+ old_count = posts(:welcome).taggings.count
156
+ tagging = posts(:welcome).taggings.create(:tag => tags(:misc))
157
+ assert_equal "Post", tagging.taggable_type
158
+ assert_equal old_count+1, posts(:welcome).taggings.count
159
+ end
160
+
161
+ def test_create_bang_polymorphic_with_has_many_scope
162
+ old_count = posts(:welcome).taggings.count
163
+ tagging = posts(:welcome).taggings.create!(:tag => tags(:misc))
164
+ assert_equal "Post", tagging.taggable_type
165
+ assert_equal old_count+1, posts(:welcome).taggings.count
166
+ end
167
+
168
+ def test_create_polymorphic_has_one_with_scope
169
+ old_count = Tagging.count
170
+ tagging = posts(:welcome).create_tagging(:tag => tags(:misc))
171
+ assert_equal "Post", tagging.taggable_type
172
+ assert_equal old_count+1, Tagging.count
173
+ end
174
+
175
+ def test_delete_polymorphic_has_many_with_delete_all
176
+ assert_equal 1, posts(:welcome).taggings.count
177
+ posts(:welcome).taggings.first.update_columns taggable_type: 'PostWithHasManyDeleteAll'
178
+ post = find_post_with_dependency(1, :has_many, :taggings, :delete_all)
179
+
180
+ old_count = Tagging.count
181
+ post.destroy
182
+ assert_equal old_count-1, Tagging.count
183
+ assert_equal 0, posts(:welcome).taggings.count
184
+ end
185
+
186
+ def test_delete_polymorphic_has_many_with_destroy
187
+ assert_equal 1, posts(:welcome).taggings.count
188
+ posts(:welcome).taggings.first.update_columns taggable_type: 'PostWithHasManyDestroy'
189
+ post = find_post_with_dependency(1, :has_many, :taggings, :destroy)
190
+
191
+ old_count = Tagging.count
192
+ post.destroy
193
+ assert_equal old_count-1, Tagging.count
194
+ assert_equal 0, posts(:welcome).taggings.count
195
+ end
196
+
197
+ def test_delete_polymorphic_has_many_with_nullify
198
+ assert_equal 1, posts(:welcome).taggings.count
199
+ posts(:welcome).taggings.first.update_columns taggable_type: 'PostWithHasManyNullify'
200
+ post = find_post_with_dependency(1, :has_many, :taggings, :nullify)
201
+
202
+ old_count = Tagging.count
203
+ post.destroy
204
+ assert_equal old_count, Tagging.count
205
+ assert_equal 0, posts(:welcome).taggings.count
206
+ end
207
+
208
+ def test_delete_polymorphic_has_one_with_destroy
209
+ assert posts(:welcome).tagging
210
+ posts(:welcome).tagging.update_columns taggable_type: 'PostWithHasOneDestroy'
211
+ post = find_post_with_dependency(1, :has_one, :tagging, :destroy)
212
+
213
+ old_count = Tagging.count
214
+ post.destroy
215
+ assert_equal old_count-1, Tagging.count
216
+ posts(:welcome).association(:tagging).reload
217
+ assert_nil posts(:welcome).tagging
218
+ end
219
+
220
+ def test_delete_polymorphic_has_one_with_nullify
221
+ assert posts(:welcome).tagging
222
+ posts(:welcome).tagging.update_columns taggable_type: 'PostWithHasOneNullify'
223
+ post = find_post_with_dependency(1, :has_one, :tagging, :nullify)
224
+
225
+ old_count = Tagging.count
226
+ post.destroy
227
+ assert_equal old_count, Tagging.count
228
+ posts(:welcome).association(:tagging).reload
229
+ assert_nil posts(:welcome).tagging
230
+ end
231
+
232
+ def test_has_many_with_piggyback
233
+ assert_equal "2", categories(:sti_test).authors_with_select.first.post_id.to_s
234
+ end
235
+
236
+ def test_create_through_has_many_with_piggyback
237
+ category = categories(:sti_test)
238
+ ernie = category.authors_with_select.create(:name => 'Ernie')
239
+ assert_nothing_raised do
240
+ assert_equal ernie, category.authors_with_select.detect {|a| a.name == 'Ernie'}
241
+ end
242
+ end
243
+
244
+ def test_include_has_many_through
245
+ posts = Post.all.merge!(:order => 'posts.id').to_a
246
+ posts_with_authors = Post.all.merge!(:includes => :authors, :order => 'posts.id').to_a
247
+ assert_equal posts.length, posts_with_authors.length
248
+ posts.length.times do |i|
249
+ assert_equal posts[i].authors.length, assert_no_queries { posts_with_authors[i].authors.length }
250
+ end
251
+ end
252
+
253
+ def test_include_polymorphic_has_one
254
+ post = Post.includes(:tagging).find posts(:welcome).id
255
+ tagging = taggings(:welcome_general)
256
+ assert_no_queries do
257
+ assert_equal tagging, post.tagging
258
+ end
259
+ end
260
+
261
+ def test_include_polymorphic_has_one_defined_in_abstract_parent
262
+ item = Item.includes(:tagging).find items(:dvd).id
263
+ tagging = taggings(:godfather)
264
+ assert_no_queries do
265
+ assert_equal tagging, item.tagging
266
+ end
267
+ end
268
+
269
+ def test_include_polymorphic_has_many_through
270
+ posts = Post.all.merge!(:order => 'posts.id').to_a
271
+ posts_with_tags = Post.all.merge!(:includes => :tags, :order => 'posts.id').to_a
272
+ assert_equal posts.length, posts_with_tags.length
273
+ posts.length.times do |i|
274
+ assert_equal posts[i].tags.length, assert_no_queries { posts_with_tags[i].tags.length }
275
+ end
276
+ end
277
+
278
+ def test_include_polymorphic_has_many
279
+ posts = Post.all.merge!(:order => 'posts.id').to_a
280
+ posts_with_taggings = Post.all.merge!(:includes => :taggings, :order => 'posts.id').to_a
281
+ assert_equal posts.length, posts_with_taggings.length
282
+ posts.length.times do |i|
283
+ assert_equal posts[i].taggings.length, assert_no_queries { posts_with_taggings[i].taggings.length }
284
+ end
285
+ end
286
+
287
+ def test_has_many_find_all
288
+ assert_equal [categories(:general)], authors(:david).categories.to_a
289
+ end
290
+
291
+ def test_has_many_find_first
292
+ assert_equal categories(:general), authors(:david).categories.first
293
+ end
294
+
295
+ def test_has_many_with_hash_conditions
296
+ assert_equal categories(:general), authors(:david).categories_like_general.first
297
+ end
298
+
299
+ def test_has_many_find_conditions
300
+ assert_equal categories(:general), authors(:david).categories.where("categories.name = 'General'").first
301
+ assert_nil authors(:david).categories.where("categories.name = 'Technology'").first
302
+ end
303
+
304
+ def test_has_many_array_methods_called_by_method_missing
305
+ assert authors(:david).categories.any? { |category| category.name == 'General' }
306
+ assert_nothing_raised { authors(:david).categories.sort }
307
+ end
308
+
309
+ def test_has_many_going_through_join_model_with_custom_foreign_key
310
+ assert_equal [authors(:bob)], posts(:thinking).authors
311
+ assert_equal [authors(:mary)], posts(:authorless).authors
312
+ end
313
+
314
+ def test_has_many_going_through_join_model_with_custom_primary_key
315
+ assert_equal [authors(:david)], posts(:thinking).authors_using_author_id
316
+ end
317
+
318
+ def test_has_many_going_through_polymorphic_join_model_with_custom_primary_key
319
+ assert_equal [tags(:general)], posts(:eager_other).tags_using_author_id
320
+ end
321
+
322
+ def test_has_many_through_with_custom_primary_key_on_belongs_to_source
323
+ assert_equal [authors(:david), authors(:david)], posts(:thinking).author_using_custom_pk
324
+ end
325
+
326
+ def test_has_many_through_with_custom_primary_key_on_has_many_source
327
+ assert_equal [authors(:david), authors(:bob)], posts(:thinking).authors_using_custom_pk.order('authors.id')
328
+ end
329
+
330
+ def test_belongs_to_polymorphic_with_counter_cache
331
+ assert_equal 1, posts(:welcome)[:tags_count]
332
+ tagging = posts(:welcome).taggings.create(:tag => tags(:general))
333
+ assert_equal 2, posts(:welcome, :reload)[:tags_count]
334
+ tagging.destroy
335
+ assert_equal 1, posts(:welcome, :reload)[:tags_count]
336
+ end
337
+
338
+ def test_unavailable_through_reflection
339
+ assert_raise(ActiveRecord::HasManyThroughAssociationNotFoundError) { authors(:david).nothings }
340
+ end
341
+
342
+ def test_has_many_through_join_model_with_conditions
343
+ assert_equal [], posts(:welcome).invalid_taggings
344
+ assert_equal [], posts(:welcome).invalid_tags
345
+ end
346
+
347
+ def test_has_many_polymorphic
348
+ assert_raise ActiveRecord::HasManyThroughAssociationPolymorphicSourceError do
349
+ tags(:general).taggables
350
+ end
351
+
352
+ assert_raise ActiveRecord::HasManyThroughAssociationPolymorphicThroughError do
353
+ taggings(:welcome_general).things
354
+ end
355
+
356
+ assert_raise ActiveRecord::EagerLoadPolymorphicError do
357
+ tags(:general).taggings.includes(:taggable).where('bogus_table.column = 1').references(:bogus_table).to_a
358
+ end
359
+ end
360
+
361
+ def test_has_many_polymorphic_with_source_type
362
+ # added sort by ID as otherwise Oracle select sometimes returned rows in different order
363
+ assert_equal posts(:welcome, :thinking).sort_by(&:id), tags(:general).tagged_posts.sort_by(&:id)
364
+ end
365
+
366
+ def test_has_many_polymorphic_associations_merges_through_scope
367
+ Tag.has_many :null_taggings, -> { none }, class_name: :Tagging
368
+ Tag.has_many :null_tagged_posts, :through => :null_taggings, :source => 'taggable', :source_type => 'Post'
369
+ assert_equal [], tags(:general).null_tagged_posts
370
+ refute_equal [], tags(:general).tagged_posts
371
+ end
372
+
373
+ def test_eager_has_many_polymorphic_with_source_type
374
+ tag_with_include = Tag.all.merge!(:includes => :tagged_posts).find(tags(:general).id)
375
+ desired = posts(:welcome, :thinking)
376
+ assert_no_queries do
377
+ # added sort by ID as otherwise test using JRuby was failing as array elements were in different order
378
+ assert_equal desired.sort_by(&:id), tag_with_include.tagged_posts.sort_by(&:id)
379
+ end
380
+ assert_equal 5, tag_with_include.taggings.length
381
+ end
382
+
383
+ def test_has_many_through_has_many_find_all
384
+ assert_equal comments(:greetings), authors(:david).comments.order('comments.id').to_a.first
385
+ end
386
+
387
+ def test_has_many_through_has_many_find_all_with_custom_class
388
+ assert_equal comments(:greetings), authors(:david).funky_comments.order('comments.id').to_a.first
389
+ end
390
+
391
+ def test_has_many_through_has_many_find_first
392
+ assert_equal comments(:greetings), authors(:david).comments.order('comments.id').first
393
+ end
394
+
395
+ def test_has_many_through_has_many_find_conditions
396
+ options = { :where => "comments.#{QUOTED_TYPE}='SpecialComment'", :order => 'comments.id' }
397
+ assert_equal comments(:does_it_hurt), authors(:david).comments.merge(options).first
398
+ end
399
+
400
+ def test_has_many_through_has_many_find_by_id
401
+ assert_equal comments(:more_greetings), authors(:david).comments.find(2)
402
+ end
403
+
404
+ def test_has_many_through_polymorphic_has_one
405
+ assert_equal Tagging.find(1,2).sort_by(&:id), authors(:david).taggings_2
406
+ end
407
+
408
+ def test_has_many_through_polymorphic_has_many
409
+ assert_equal taggings(:welcome_general, :thinking_general), authors(:david).taggings.distinct.sort_by(&:id)
410
+ end
411
+
412
+ def test_include_has_many_through_polymorphic_has_many
413
+ author = Author.includes(:taggings).find authors(:david).id
414
+ expected_taggings = taggings(:welcome_general, :thinking_general)
415
+ assert_no_queries do
416
+ assert_equal expected_taggings, author.taggings.distinct.sort_by(&:id)
417
+ end
418
+ end
419
+
420
+ def test_eager_load_has_many_through_has_many
421
+ author = Author.all.merge!(:where => ['name = ?', 'David'], :includes => :comments, :order => 'comments.id').first
422
+ SpecialComment.new; VerySpecialComment.new
423
+ assert_no_queries do
424
+ assert_equal [1,2,3,5,6,7,8,9,10,12], author.comments.collect(&:id)
425
+ end
426
+ end
427
+
428
+ def test_eager_load_has_many_through_has_many_with_conditions
429
+ post = Post.all.merge!(:includes => :invalid_tags).first
430
+ assert_no_queries do
431
+ post.invalid_tags
432
+ end
433
+ end
434
+
435
+ def test_eager_belongs_to_and_has_one_not_singularized
436
+ assert_nothing_raised do
437
+ Author.all.merge!(:includes => :author_address).first
438
+ AuthorAddress.all.merge!(:includes => :author).first
439
+ end
440
+ end
441
+
442
+ def test_self_referential_has_many_through
443
+ assert_equal [authors(:mary)], authors(:david).favorite_authors
444
+ assert_equal [], authors(:mary).favorite_authors
445
+ end
446
+
447
+ def test_add_to_self_referential_has_many_through
448
+ new_author = Author.create(:name => "Bob")
449
+ authors(:david).author_favorites.create :favorite_author => new_author
450
+ assert_equal new_author, authors(:david).reload.favorite_authors.first
451
+ end
452
+
453
+ def test_has_many_through_uses_conditions_specified_on_the_has_many_association
454
+ author = Author.first
455
+ assert author.comments.present?
456
+ assert author.nonexistent_comments.blank?
457
+ end
458
+
459
+ def test_has_many_through_uses_correct_attributes
460
+ assert_nil posts(:thinking).tags.find_by_name("General").attributes["tag_id"]
461
+ end
462
+
463
+ def test_associating_unsaved_records_with_has_many_through
464
+ saved_post = posts(:thinking)
465
+ new_tag = Tag.new(:name => "new")
466
+
467
+ saved_post.tags << new_tag
468
+ assert new_tag.persisted? #consistent with habtm!
469
+ assert saved_post.persisted?
470
+ assert saved_post.tags.include?(new_tag)
471
+
472
+ assert new_tag.persisted?
473
+ assert saved_post.reload.tags.reload.include?(new_tag)
474
+
475
+
476
+ new_post = Post.new(:title => "Association replacement works!", :body => "You best believe it.")
477
+ saved_tag = tags(:general)
478
+
479
+ new_post.tags << saved_tag
480
+ assert !new_post.persisted?
481
+ assert saved_tag.persisted?
482
+ assert new_post.tags.include?(saved_tag)
483
+
484
+ new_post.save!
485
+ assert new_post.persisted?
486
+ assert new_post.reload.tags.reload.include?(saved_tag)
487
+
488
+ assert !posts(:thinking).tags.build.persisted?
489
+ assert !posts(:thinking).tags.new.persisted?
490
+ end
491
+
492
+ def test_create_associate_when_adding_to_has_many_through
493
+ count = posts(:thinking).tags.count
494
+ push = Tag.create!(:name => 'pushme')
495
+ post_thinking = posts(:thinking)
496
+ assert_nothing_raised { post_thinking.tags << push }
497
+ assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
498
+ message = "Expected a Tag in tags collection, got #{wrong.class}.")
499
+ assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
500
+ message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
501
+ assert_equal(count + 1, post_thinking.reload.tags.size)
502
+ assert_equal(count + 1, post_thinking.tags.reload.size)
503
+
504
+ assert_kind_of Tag, post_thinking.tags.create!(:name => 'foo')
505
+ assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
506
+ message = "Expected a Tag in tags collection, got #{wrong.class}.")
507
+ assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
508
+ message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
509
+ assert_equal(count + 2, post_thinking.reload.tags.size)
510
+ assert_equal(count + 2, post_thinking.tags.reload.size)
511
+
512
+ assert_nothing_raised { post_thinking.tags.concat(Tag.create!(:name => 'abc'), Tag.create!(:name => 'def')) }
513
+ assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
514
+ message = "Expected a Tag in tags collection, got #{wrong.class}.")
515
+ assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
516
+ message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
517
+ assert_equal(count + 4, post_thinking.reload.tags.size)
518
+ assert_equal(count + 4, post_thinking.tags.reload.size)
519
+
520
+ # Raises if the wrong reflection name is used to set the Edge belongs_to
521
+ assert_nothing_raised { vertices(:vertex_1).sinks << vertices(:vertex_5) }
522
+ end
523
+
524
+ def test_add_to_join_table_with_no_id
525
+ assert_nothing_raised { vertices(:vertex_1).sinks << vertices(:vertex_5) }
526
+ end
527
+
528
+ def test_has_many_through_collection_size_doesnt_load_target_if_not_loaded
529
+ author = authors(:david)
530
+ assert_equal 10, author.comments.size
531
+ assert !author.comments.loaded?
532
+ end
533
+
534
+ def test_has_many_through_collection_size_uses_counter_cache_if_it_exists
535
+ c = categories(:general)
536
+ c.categorizations_count = 100
537
+ assert_equal 100, c.categorizations.size
538
+ assert !c.categorizations.loaded?
539
+ end
540
+
541
+ def test_adding_junk_to_has_many_through_should_raise_type_mismatch
542
+ assert_raise(ActiveRecord::AssociationTypeMismatch) { posts(:thinking).tags << "Uhh what now?" }
543
+ end
544
+
545
+ def test_adding_to_has_many_through_should_return_self
546
+ tags = posts(:thinking).tags
547
+ assert_equal tags, posts(:thinking).tags.push(tags(:general))
548
+ end
549
+
550
+ def test_delete_associate_when_deleting_from_has_many_through_with_nonstandard_id
551
+ count = books(:awdr).references.count
552
+ references_before = books(:awdr).references
553
+ book = Book.create!(:name => 'Getting Real')
554
+ book_awdr = books(:awdr)
555
+ book_awdr.references << book
556
+ assert_equal(count + 1, book_awdr.references.reload.size)
557
+
558
+ assert_nothing_raised { book_awdr.references.delete(book) }
559
+ assert_equal(count, book_awdr.references.size)
560
+ assert_equal(count, book_awdr.references.reload.size)
561
+ assert_equal(references_before.sort, book_awdr.references.sort)
562
+ end
563
+
564
+ def test_delete_associate_when_deleting_from_has_many_through
565
+ count = posts(:thinking).tags.count
566
+ tags_before = posts(:thinking).tags.sort
567
+ tag = Tag.create!(:name => 'doomed')
568
+ post_thinking = posts(:thinking)
569
+ post_thinking.tags << tag
570
+ assert_equal(count + 1, post_thinking.taggings.reload.size)
571
+ assert_equal(count + 1, post_thinking.reload.tags.reload.size)
572
+ assert_not_equal(tags_before, post_thinking.tags.sort)
573
+
574
+ assert_nothing_raised { post_thinking.tags.delete(tag) }
575
+ assert_equal(count, post_thinking.tags.size)
576
+ assert_equal(count, post_thinking.tags.reload.size)
577
+ assert_equal(count, post_thinking.taggings.reload.size)
578
+ assert_equal(tags_before, post_thinking.tags.sort)
579
+ end
580
+
581
+ def test_delete_associate_when_deleting_from_has_many_through_with_multiple_tags
582
+ count = posts(:thinking).tags.count
583
+ tags_before = posts(:thinking).tags.sort
584
+ doomed = Tag.create!(:name => 'doomed')
585
+ doomed2 = Tag.create!(:name => 'doomed2')
586
+ quaked = Tag.create!(:name => 'quaked')
587
+ post_thinking = posts(:thinking)
588
+ post_thinking.tags << doomed << doomed2
589
+ assert_equal(count + 2, post_thinking.reload.tags.reload.size)
590
+
591
+ assert_nothing_raised { post_thinking.tags.delete(doomed, doomed2, quaked) }
592
+ assert_equal(count, post_thinking.tags.size)
593
+ assert_equal(count, post_thinking.tags.reload.size)
594
+ assert_equal(tags_before, post_thinking.tags.sort)
595
+ end
596
+
597
+ def test_deleting_junk_from_has_many_through_should_raise_type_mismatch
598
+ assert_raise(ActiveRecord::AssociationTypeMismatch) { posts(:thinking).tags.delete(Object.new) }
599
+ end
600
+
601
+ def test_deleting_by_integer_id_from_has_many_through
602
+ post = posts(:thinking)
603
+
604
+ assert_difference 'post.tags.count', -1 do
605
+ assert_equal 1, post.tags.delete(1).size
606
+ end
607
+
608
+ assert_equal 0, post.tags.size
609
+ end
610
+
611
+ def test_deleting_by_string_id_from_has_many_through
612
+ post = posts(:thinking)
613
+
614
+ assert_difference 'post.tags.count', -1 do
615
+ assert_equal 1, post.tags.delete('1').size
616
+ end
617
+
618
+ assert_equal 0, post.tags.size
619
+ end
620
+
621
+ def test_has_many_through_sum_uses_calculations
622
+ assert_nothing_raised { authors(:david).comments.sum(:post_id) }
623
+ end
624
+
625
+ def test_calculations_on_has_many_through_should_disambiguate_fields
626
+ assert_nothing_raised { authors(:david).categories.maximum(:id) }
627
+ end
628
+
629
+ def test_calculations_on_has_many_through_should_not_disambiguate_fields_unless_necessary
630
+ assert_nothing_raised { authors(:david).categories.maximum("categories.id") }
631
+ end
632
+
633
+ def test_has_many_through_has_many_with_sti
634
+ assert_equal [comments(:does_it_hurt)], authors(:david).special_post_comments
635
+ end
636
+
637
+ def test_distinct_has_many_through_should_retain_order
638
+ comment_ids = authors(:david).comments.map(&:id)
639
+ assert_equal comment_ids.sort, authors(:david).ordered_uniq_comments.map(&:id)
640
+ assert_equal comment_ids.sort.reverse, authors(:david).ordered_uniq_comments_desc.map(&:id)
641
+ end
642
+
643
+ def test_polymorphic_has_many
644
+ expected = taggings(:welcome_general)
645
+ p = Post.all.merge!(:includes => :taggings).find(posts(:welcome).id)
646
+ assert_no_queries {assert p.taggings.include?(expected)}
647
+ assert posts(:welcome).taggings.include?(taggings(:welcome_general))
648
+ end
649
+
650
+ def test_polymorphic_has_one
651
+ expected = posts(:welcome)
652
+
653
+ tagging = Tagging.all.merge!(:includes => :taggable).find(taggings(:welcome_general).id)
654
+ assert_no_queries { assert_equal expected, tagging.taggable}
655
+ end
656
+
657
+ def test_polymorphic_belongs_to
658
+ p = Post.all.merge!(:includes => {:taggings => :taggable}).find(posts(:welcome).id)
659
+ assert_no_queries {assert_equal posts(:welcome), p.taggings.first.taggable}
660
+ end
661
+
662
+ def test_preload_polymorphic_has_many_through
663
+ posts = Post.all.merge!(:order => 'posts.id').to_a
664
+ posts_with_tags = Post.all.merge!(:includes => :tags, :order => 'posts.id').to_a
665
+ assert_equal posts.length, posts_with_tags.length
666
+ posts.length.times do |i|
667
+ assert_equal posts[i].tags.length, assert_no_queries { posts_with_tags[i].tags.length }
668
+ end
669
+ end
670
+
671
+ def test_preload_polymorph_many_types
672
+ taggings = Tagging.all.merge!(:includes => :taggable, :where => ['taggable_type != ?', 'FakeModel']).to_a
673
+ assert_no_queries do
674
+ taggings.first.taggable.id
675
+ taggings[1].taggable.id
676
+ end
677
+
678
+ taggables = taggings.map(&:taggable)
679
+ assert taggables.include?(items(:dvd))
680
+ assert taggables.include?(posts(:welcome))
681
+ end
682
+
683
+ def test_preload_nil_polymorphic_belongs_to
684
+ assert_nothing_raised do
685
+ Tagging.all.merge!(:includes => :taggable, :where => ['taggable_type IS NULL']).to_a
686
+ end
687
+ end
688
+
689
+ def test_preload_polymorphic_has_many
690
+ posts = Post.all.merge!(:order => 'posts.id').to_a
691
+ posts_with_taggings = Post.all.merge!(:includes => :taggings, :order => 'posts.id').to_a
692
+ assert_equal posts.length, posts_with_taggings.length
693
+ posts.length.times do |i|
694
+ assert_equal posts[i].taggings.length, assert_no_queries { posts_with_taggings[i].taggings.length }
695
+ end
696
+ end
697
+
698
+ def test_belongs_to_shared_parent
699
+ comments = Comment.all.merge!(:includes => :post, :where => 'post_id = 1').to_a
700
+ assert_no_queries do
701
+ assert_equal comments.first.post, comments[1].post
702
+ end
703
+ end
704
+
705
+ def test_has_many_through_include_uses_array_include_after_loaded
706
+ david = authors(:david)
707
+ david.categories.load_target
708
+
709
+ category = david.categories.first
710
+
711
+ assert_no_queries do
712
+ assert david.categories.loaded?
713
+ assert david.categories.include?(category)
714
+ end
715
+ end
716
+
717
+ def test_has_many_through_include_checks_if_record_exists_if_target_not_loaded
718
+ david = authors(:david)
719
+ category = david.categories.first
720
+
721
+ david.reload
722
+ assert ! david.categories.loaded?
723
+ assert_queries(1) do
724
+ assert david.categories.include?(category)
725
+ end
726
+ assert ! david.categories.loaded?
727
+ end
728
+
729
+ def test_has_many_through_include_returns_false_for_non_matching_record_to_verify_scoping
730
+ david = authors(:david)
731
+ category = Category.create!(:name => 'Not Associated')
732
+
733
+ assert ! david.categories.loaded?
734
+ assert ! david.categories.include?(category)
735
+ end
736
+
737
+ def test_has_many_through_goes_through_all_sti_classes
738
+ sub_sti_post = SubStiPost.create!(:title => 'test', :body => 'test', :author_id => 1)
739
+ new_comment = sub_sti_post.comments.create(:body => 'test')
740
+
741
+ assert_equal [9, 10, new_comment.id], authors(:david).sti_post_comments.map(&:id).sort
742
+ end
743
+
744
+ def test_has_many_with_pluralize_table_names_false
745
+ aircraft = Aircraft.create!(:name => "Airbus 380")
746
+ engine = Engine.create!(:car_id => aircraft.id)
747
+ assert_equal aircraft.engines, [engine]
748
+ end
749
+
750
+ def test_proper_error_message_for_eager_load_and_includes_association_errors
751
+ includes_error = assert_raises(ActiveRecord::ConfigurationError) {
752
+ Post.includes(:nonexistent_relation).where(nonexistent_relation: {name: 'Rochester'}).find(1)
753
+ }
754
+ assert_equal("Can't join 'Post' to association named 'nonexistent_relation'; perhaps you misspelled it?", includes_error.message)
755
+
756
+ eager_load_error = assert_raises(ActiveRecord::ConfigurationError) {
757
+ Post.eager_load(:nonexistent_relation).where(nonexistent_relation: {name: 'Rochester'}).find(1)
758
+ }
759
+ assert_equal("Can't join 'Post' to association named 'nonexistent_relation'; perhaps you misspelled it?", eager_load_error.message)
760
+
761
+ includes_and_eager_load_error = assert_raises(ActiveRecord::ConfigurationError) {
762
+ Post.eager_load(:nonexistent_relation).includes(:nonexistent_relation).where(nonexistent_relation: {name: 'Rochester'}).find(1)
763
+ }
764
+ assert_equal("Can't join 'Post' to association named 'nonexistent_relation'; perhaps you misspelled it?", includes_and_eager_load_error.message)
765
+ end
766
+
767
+ private
768
+ # create dynamic Post models to allow different dependency options
769
+ def find_post_with_dependency(post_id, association, association_name, dependency)
770
+ class_name = "PostWith#{association.to_s.classify}#{dependency.to_s.classify}"
771
+ Post.find(post_id).update_columns type: class_name
772
+ klass = Object.const_set(class_name, Class.new(ActiveRecord::Base))
773
+ klass.table_name = 'posts'
774
+ klass.send(association, association_name, :as => :taggable, :dependent => dependency)
775
+ klass.find(post_id)
776
+ end
777
+ end