ibm_db 3.0.4-x86-mingw32 → 3.0.5-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 (463) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +4 -1
  3. data/LICENSE +1 -1
  4. data/MANIFEST +14 -14
  5. data/README +225 -225
  6. data/ext/Makefile.nt32 +181 -181
  7. data/ext/Makefile.nt32.191 +212 -212
  8. data/ext/extconf.rb +291 -291
  9. data/ext/ibm_db.c +11887 -11884
  10. data/ext/ruby_ibm_db.h +241 -241
  11. data/ext/ruby_ibm_db_cli.c +866 -866
  12. data/ext/ruby_ibm_db_cli.h +500 -500
  13. data/init.rb +41 -41
  14. data/lib/IBM_DB.rb +27 -27
  15. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +3177 -3177
  16. data/lib/active_record/connection_adapters/ibmdb_adapter.rb +1 -1
  17. data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -328
  18. data/lib/mswin32/ibm_db.rb +122 -122
  19. data/lib/mswin32/rb21x/i386/ibm_db.so +0 -0
  20. data/lib/mswin32/rb22x/i386/ibm_db.so +0 -0
  21. data/lib/mswin32/rb23x/i386/ibm_db.so +0 -0
  22. data/test/active_record/connection_adapters/fake_adapter.rb +46 -46
  23. data/test/assets/example.log +1 -1
  24. data/test/assets/test.txt +1 -1
  25. data/test/cases/adapter_test.rb +276 -261
  26. data/test/cases/aggregations_test.rb +158 -158
  27. data/test/cases/ar_schema_test.rb +161 -161
  28. data/test/cases/associations/association_scope_test.rb +21 -21
  29. data/test/cases/associations/belongs_to_associations_test.rb +1029 -1029
  30. data/test/cases/associations/callbacks_test.rb +192 -192
  31. data/test/cases/associations/cascaded_eager_loading_test.rb +188 -188
  32. data/test/cases/associations/deprecated_counter_cache_on_has_many_through_test.rb +26 -26
  33. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +36 -36
  34. data/test/cases/associations/eager_load_nested_include_test.rb +128 -128
  35. data/test/cases/associations/eager_singularization_test.rb +148 -148
  36. data/test/cases/associations/eager_test.rb +1429 -1411
  37. data/test/cases/associations/extension_test.rb +82 -82
  38. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +972 -932
  39. data/test/cases/associations/has_many_associations_test.rb +2182 -2162
  40. data/test/cases/associations/has_many_through_associations_test.rb +1204 -1204
  41. data/test/cases/associations/has_one_associations_test.rb +610 -610
  42. data/test/cases/associations/has_one_through_associations_test.rb +380 -380
  43. data/test/cases/associations/inner_join_association_test.rb +139 -139
  44. data/test/cases/associations/inverse_associations_test.rb +706 -693
  45. data/test/cases/associations/join_model_test.rb +754 -754
  46. data/test/cases/associations/nested_through_associations_test.rb +579 -579
  47. data/test/cases/associations/required_test.rb +82 -82
  48. data/test/cases/associations_test.rb +380 -380
  49. data/test/cases/attribute_decorators_test.rb +125 -125
  50. data/test/cases/attribute_methods/read_test.rb +60 -60
  51. data/test/cases/attribute_methods/serialization_test.rb +29 -29
  52. data/test/cases/attribute_methods_test.rb +952 -952
  53. data/test/cases/attribute_set_test.rb +210 -200
  54. data/test/cases/attribute_test.rb +180 -180
  55. data/test/cases/attributes_test.rb +136 -136
  56. data/test/cases/autosave_association_test.rb +1595 -1595
  57. data/test/cases/base_test.rb +1664 -1638
  58. data/test/cases/batches_test.rb +212 -212
  59. data/test/cases/binary_test.rb +52 -52
  60. data/test/cases/bind_parameter_test.rb +100 -100
  61. data/test/cases/calculations_test.rb +646 -646
  62. data/test/cases/callbacks_test.rb +543 -543
  63. data/test/cases/clone_test.rb +40 -40
  64. data/test/cases/coders/yaml_column_test.rb +63 -63
  65. data/test/cases/column_alias_test.rb +17 -17
  66. data/test/cases/column_definition_test.rb +123 -123
  67. data/test/cases/connection_adapters/adapter_leasing_test.rb +54 -54
  68. data/test/cases/connection_adapters/connection_handler_test.rb +53 -53
  69. data/test/cases/connection_adapters/connection_specification_test.rb +12 -12
  70. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +293 -293
  71. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +65 -65
  72. data/test/cases/connection_adapters/quoting_test.rb +13 -13
  73. data/test/cases/connection_adapters/schema_cache_test.rb +56 -56
  74. data/test/cases/connection_adapters/type_lookup_test.rb +110 -110
  75. data/test/cases/connection_management_test.rb +122 -122
  76. data/test/cases/connection_pool_test.rb +346 -346
  77. data/test/cases/connection_specification/resolver_test.rb +116 -116
  78. data/test/cases/core_test.rb +112 -112
  79. data/test/cases/counter_cache_test.rb +209 -209
  80. data/test/cases/custom_locking_test.rb +17 -17
  81. data/test/cases/database_statements_test.rb +19 -19
  82. data/test/cases/date_time_test.rb +61 -61
  83. data/test/cases/defaults_test.rb +223 -223
  84. data/test/cases/dirty_test.rb +785 -775
  85. data/test/cases/disconnected_test.rb +28 -28
  86. data/test/cases/dup_test.rb +157 -157
  87. data/test/cases/enum_test.rb +290 -290
  88. data/test/cases/explain_subscriber_test.rb +64 -64
  89. data/test/cases/explain_test.rb +76 -76
  90. data/test/cases/finder_respond_to_test.rb +60 -60
  91. data/test/cases/finder_test.rb +1169 -1166
  92. data/test/cases/fixture_set/file_test.rb +138 -138
  93. data/test/cases/fixtures_test.rb +908 -897
  94. data/test/cases/forbidden_attributes_protection_test.rb +99 -99
  95. data/test/cases/habtm_destroy_order_test.rb +61 -61
  96. data/test/cases/helper.rb +210 -210
  97. data/test/cases/hot_compatibility_test.rb +54 -54
  98. data/test/cases/i18n_test.rb +45 -45
  99. data/test/cases/inheritance_test.rb +375 -375
  100. data/test/cases/integration_test.rb +139 -139
  101. data/test/cases/invalid_connection_test.rb +22 -22
  102. data/test/cases/invalid_date_test.rb +32 -32
  103. data/test/cases/invertible_migration_test.rb +295 -295
  104. data/test/cases/json_serialization_test.rb +302 -302
  105. data/test/cases/locking_test.rb +477 -477
  106. data/test/cases/log_subscriber_test.rb +136 -136
  107. data/test/cases/migration/change_schema_test - Copy.rb +448 -448
  108. data/test/cases/migration/change_schema_test.rb +512 -472
  109. data/test/cases/migration/change_table_test.rb +224 -224
  110. data/test/cases/migration/column_attributes_test.rb +192 -192
  111. data/test/cases/migration/column_positioning_test.rb +56 -56
  112. data/test/cases/migration/columns_test.rb +304 -304
  113. data/test/cases/migration/command_recorder_test.rb +305 -305
  114. data/test/cases/migration/create_join_table_test.rb +148 -148
  115. data/test/cases/migration/foreign_key_test - Changed.rb +325 -325
  116. data/test/cases/migration/foreign_key_test.rb +328 -360
  117. data/test/cases/migration/helper.rb +39 -39
  118. data/test/cases/migration/index_test.rb +216 -216
  119. data/test/cases/migration/logger_test.rb +36 -36
  120. data/test/cases/migration/pending_migrations_test.rb +53 -53
  121. data/test/cases/migration/references_foreign_key_test.rb +169 -214
  122. data/test/cases/migration/references_index_test.rb +101 -101
  123. data/test/cases/migration/references_statements_test.rb +116 -116
  124. data/test/cases/migration/rename_table_test.rb +93 -93
  125. data/test/cases/migration/table_and_index_test.rb +24 -24
  126. data/test/cases/migration_test.rb +959 -959
  127. data/test/cases/migrator_test.rb +388 -388
  128. data/test/cases/mixin_test.rb +70 -70
  129. data/test/cases/modules_test.rb +173 -173
  130. data/test/cases/multiparameter_attributes_test.rb +350 -350
  131. data/test/cases/multiple_db_test.rb +115 -115
  132. data/test/cases/nested_attributes_test.rb +1070 -1057
  133. data/test/cases/nested_attributes_with_callbacks_test.rb +144 -144
  134. data/test/cases/persistence_test.rb +909 -909
  135. data/test/cases/pooled_connections_test.rb +81 -81
  136. data/test/cases/primary_keys_test.rb +237 -237
  137. data/test/cases/query_cache_test.rb +326 -326
  138. data/test/cases/quoting_test.rb +156 -156
  139. data/test/cases/readonly_test.rb +118 -118
  140. data/test/cases/reaper_test.rb +85 -85
  141. data/test/cases/reflection_test.rb +463 -454
  142. data/test/cases/relation/delegation_test.rb +68 -68
  143. data/test/cases/relation/merging_test.rb +161 -161
  144. data/test/cases/relation/mutation_test.rb +165 -165
  145. data/test/cases/relation/predicate_builder_test.rb +14 -14
  146. data/test/cases/relation/where_chain_test.rb +181 -181
  147. data/test/cases/relation/where_test.rb +300 -300
  148. data/test/cases/relation/where_test2.rb +36 -36
  149. data/test/cases/relation_test.rb +319 -297
  150. data/test/cases/relations_test.rb +1815 -1815
  151. data/test/cases/reload_models_test.rb +22 -22
  152. data/test/cases/result_test.rb +80 -80
  153. data/test/cases/sanitize_test.rb +83 -83
  154. data/test/cases/schema_dumper_test.rb +463 -463
  155. data/test/cases/scoping/default_scoping_test.rb +454 -454
  156. data/test/cases/scoping/named_scoping_test.rb +524 -524
  157. data/test/cases/scoping/relation_scoping_test.rb +357 -357
  158. data/test/cases/serialization_test.rb +104 -104
  159. data/test/cases/serialized_attribute_test.rb +277 -277
  160. data/test/cases/statement_cache_test.rb +98 -98
  161. data/test/cases/store_test.rb +194 -194
  162. data/test/cases/tasks/database_tasks_test.rb +398 -396
  163. data/test/cases/tasks/mysql_rake_test.rb +324 -311
  164. data/test/cases/tasks/postgresql_rake_test.rb +250 -245
  165. data/test/cases/tasks/sqlite_rake_test.rb +193 -193
  166. data/test/cases/test_case.rb +123 -123
  167. data/test/cases/timestamp_test.rb +467 -468
  168. data/test/cases/transaction_callbacks_test.rb +452 -452
  169. data/test/cases/transaction_isolation_test.rb +106 -106
  170. data/test/cases/transactions_test.rb +817 -817
  171. data/test/cases/type/decimal_test.rb +56 -51
  172. data/test/cases/type/integer_test.rb +121 -121
  173. data/test/cases/type/string_test.rb +36 -36
  174. data/test/cases/type/type_map_test.rb +177 -177
  175. data/test/cases/type/unsigned_integer_test.rb +18 -18
  176. data/test/cases/types_test.rb +141 -141
  177. data/test/cases/unconnected_test.rb +33 -33
  178. data/test/cases/validations/association_validation_test.rb +86 -86
  179. data/test/cases/validations/i18n_generate_message_validation_test.rb +84 -84
  180. data/test/cases/validations/i18n_validation_test.rb +90 -90
  181. data/test/cases/validations/length_validation_test.rb +47 -47
  182. data/test/cases/validations/presence_validation_test.rb +68 -68
  183. data/test/cases/validations/uniqueness_validation_test.rb +457 -434
  184. data/test/cases/validations_repair_helper.rb +23 -23
  185. data/test/cases/validations_test.rb +165 -165
  186. data/test/cases/view_test.rb +119 -113
  187. data/test/cases/xml_serialization_test.rb +457 -457
  188. data/test/cases/yaml_serialization_test.rb +126 -86
  189. data/test/config.rb +5 -5
  190. data/test/config.yml +154 -154
  191. data/test/connections/native_ibm_db/connection.rb +43 -43
  192. data/test/fixtures/accounts.yml +29 -29
  193. data/test/fixtures/admin/accounts.yml +2 -2
  194. data/test/fixtures/admin/randomly_named_a9.yml +7 -7
  195. data/test/fixtures/admin/randomly_named_b0.yml +7 -7
  196. data/test/fixtures/admin/users.yml +10 -10
  197. data/test/fixtures/author_addresses.yml +17 -17
  198. data/test/fixtures/author_favorites.yml +3 -3
  199. data/test/fixtures/authors.yml +23 -23
  200. data/test/fixtures/binaries.yml +133 -133
  201. data/test/fixtures/books.yml +11 -11
  202. data/test/fixtures/bulbs.yml +5 -5
  203. data/test/fixtures/cars.yml +9 -9
  204. data/test/fixtures/categories.yml +19 -19
  205. data/test/fixtures/categories/special_categories.yml +9 -9
  206. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -4
  207. data/test/fixtures/categories_ordered.yml +7 -7
  208. data/test/fixtures/categories_posts.yml +31 -31
  209. data/test/fixtures/categorizations.yml +23 -23
  210. data/test/fixtures/clubs.yml +8 -8
  211. data/test/fixtures/collections.yml +3 -3
  212. data/test/fixtures/colleges.yml +3 -3
  213. data/test/fixtures/comments.yml +65 -65
  214. data/test/fixtures/companies.yml +67 -67
  215. data/test/fixtures/computers.yml +10 -10
  216. data/test/fixtures/courses.yml +8 -8
  217. data/test/fixtures/customers.yml +25 -25
  218. data/test/fixtures/dashboards.yml +6 -6
  219. data/test/fixtures/developers.yml +21 -21
  220. data/test/fixtures/developers_projects.yml +16 -16
  221. data/test/fixtures/dog_lovers.yml +7 -7
  222. data/test/fixtures/dogs.yml +4 -4
  223. data/test/fixtures/doubloons.yml +3 -3
  224. data/test/fixtures/edges.yml +5 -5
  225. data/test/fixtures/entrants.yml +14 -14
  226. data/test/fixtures/essays.yml +6 -6
  227. data/test/fixtures/faces.yml +11 -11
  228. data/test/fixtures/fk_test_has_fk.yml +3 -3
  229. data/test/fixtures/fk_test_has_pk.yml +1 -1
  230. data/test/fixtures/friendships.yml +4 -4
  231. data/test/fixtures/funny_jokes.yml +10 -10
  232. data/test/fixtures/interests.yml +33 -33
  233. data/test/fixtures/items.yml +3 -3
  234. data/test/fixtures/jobs.yml +7 -7
  235. data/test/fixtures/legacy_things.yml +3 -3
  236. data/test/fixtures/mateys.yml +4 -4
  237. data/test/fixtures/member_details.yml +8 -8
  238. data/test/fixtures/member_types.yml +6 -6
  239. data/test/fixtures/members.yml +11 -11
  240. data/test/fixtures/memberships.yml +34 -34
  241. data/test/fixtures/men.yml +5 -5
  242. data/test/fixtures/minimalistics.yml +2 -2
  243. data/test/fixtures/minivans.yml +5 -5
  244. data/test/fixtures/mixed_case_monkeys.yml +6 -6
  245. data/test/fixtures/mixins.yml +29 -29
  246. data/test/fixtures/movies.yml +7 -7
  247. data/test/fixtures/naked/csv/accounts.csv +1 -1
  248. data/test/fixtures/naked/yml/accounts.yml +1 -1
  249. data/test/fixtures/naked/yml/companies.yml +1 -1
  250. data/test/fixtures/naked/yml/courses.yml +1 -1
  251. data/test/fixtures/organizations.yml +5 -5
  252. data/test/fixtures/other_topics.yml +42 -42
  253. data/test/fixtures/owners.yml +9 -9
  254. data/test/fixtures/parrots.yml +27 -27
  255. data/test/fixtures/parrots_pirates.yml +7 -7
  256. data/test/fixtures/people.yml +24 -24
  257. data/test/fixtures/peoples_treasures.yml +3 -3
  258. data/test/fixtures/pets.yml +19 -19
  259. data/test/fixtures/pirates.yml +12 -12
  260. data/test/fixtures/posts.yml +80 -80
  261. data/test/fixtures/price_estimates.yml +7 -7
  262. data/test/fixtures/products.yml +4 -4
  263. data/test/fixtures/projects.yml +7 -7
  264. data/test/fixtures/randomly_named_a9.yml +7 -7
  265. data/test/fixtures/ratings.yml +14 -14
  266. data/test/fixtures/readers.yml +11 -11
  267. data/test/fixtures/references.yml +17 -17
  268. data/test/fixtures/reserved_words/distinct.yml +5 -5
  269. data/test/fixtures/reserved_words/distinct_select.yml +11 -11
  270. data/test/fixtures/reserved_words/group.yml +14 -14
  271. data/test/fixtures/reserved_words/select.yml +8 -8
  272. data/test/fixtures/reserved_words/values.yml +7 -7
  273. data/test/fixtures/ships.yml +6 -6
  274. data/test/fixtures/speedometers.yml +8 -8
  275. data/test/fixtures/sponsors.yml +12 -12
  276. data/test/fixtures/string_key_objects.yml +7 -7
  277. data/test/fixtures/subscribers.yml +10 -10
  278. data/test/fixtures/subscriptions.yml +12 -12
  279. data/test/fixtures/taggings.yml +78 -78
  280. data/test/fixtures/tags.yml +11 -11
  281. data/test/fixtures/tasks.yml +7 -7
  282. data/test/fixtures/teapots.yml +3 -3
  283. data/test/fixtures/to_be_linked/accounts.yml +2 -2
  284. data/test/fixtures/to_be_linked/users.yml +10 -10
  285. data/test/fixtures/topics.yml +49 -49
  286. data/test/fixtures/toys.yml +14 -14
  287. data/test/fixtures/traffic_lights.yml +9 -9
  288. data/test/fixtures/treasures.yml +10 -10
  289. data/test/fixtures/uuid_children.yml +3 -3
  290. data/test/fixtures/uuid_parents.yml +2 -2
  291. data/test/fixtures/variants.yml +4 -4
  292. data/test/fixtures/vegetables.yml +19 -19
  293. data/test/fixtures/vertices.yml +3 -3
  294. data/test/fixtures/warehouse_things.yml +2 -2
  295. data/test/fixtures/zines.yml +5 -5
  296. data/test/ibm_db_test.rb +24 -24
  297. data/test/migrations/10_urban/9_add_expressions.rb +11 -11
  298. data/test/migrations/decimal/1_give_me_big_numbers.rb +15 -15
  299. data/test/migrations/magic/1_currencies_have_symbols.rb +12 -12
  300. data/test/migrations/missing/1000_people_have_middle_names.rb +8 -8
  301. data/test/migrations/missing/1_people_have_last_names.rb +8 -8
  302. data/test/migrations/missing/3_we_need_reminders.rb +11 -11
  303. data/test/migrations/missing/4_innocent_jointable.rb +11 -11
  304. data/test/migrations/rename/1_we_need_things.rb +10 -10
  305. data/test/migrations/rename/2_rename_things.rb +8 -8
  306. data/test/migrations/to_copy/1_people_have_hobbies.rb +9 -9
  307. data/test/migrations/to_copy/2_people_have_descriptions.rb +9 -9
  308. data/test/migrations/to_copy2/1_create_articles.rb +7 -7
  309. data/test/migrations/to_copy2/2_create_comments.rb +7 -7
  310. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +9 -9
  311. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +9 -9
  312. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +9 -9
  313. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +7 -7
  314. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +7 -7
  315. data/test/migrations/valid/1_valid_people_have_last_names.rb +9 -9
  316. data/test/migrations/valid/2_we_need_reminders.rb +11 -11
  317. data/test/migrations/valid/3_innocent_jointable.rb +11 -11
  318. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +9 -9
  319. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +11 -11
  320. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +11 -11
  321. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +9 -9
  322. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +12 -12
  323. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +12 -12
  324. data/test/migrations/version_check/20131219224947_migration_version_check.rb +8 -8
  325. data/test/models/admin.rb +4 -4
  326. data/test/models/admin/account.rb +2 -2
  327. data/test/models/admin/randomly_named_c1.rb +3 -3
  328. data/test/models/admin/user.rb +40 -40
  329. data/test/models/aircraft.rb +4 -4
  330. data/test/models/arunit2_model.rb +3 -3
  331. data/test/models/author.rb +212 -212
  332. data/test/models/auto_id.rb +4 -4
  333. data/test/models/autoloadable/extra_firm.rb +2 -2
  334. data/test/models/binary.rb +1 -1
  335. data/test/models/bird.rb +12 -12
  336. data/test/models/book.rb +18 -18
  337. data/test/models/boolean.rb +2 -2
  338. data/test/models/bulb.rb +51 -51
  339. data/test/models/cake_designer.rb +3 -3
  340. data/test/models/car.rb +26 -26
  341. data/test/models/carrier.rb +2 -2
  342. data/test/models/categorization.rb +19 -19
  343. data/test/models/category.rb +35 -35
  344. data/test/models/chef.rb +7 -3
  345. data/test/models/citation.rb +3 -3
  346. data/test/models/club.rb +23 -23
  347. data/test/models/college.rb +10 -10
  348. data/test/models/column.rb +3 -3
  349. data/test/models/column_name.rb +3 -3
  350. data/test/models/comment.rb +64 -64
  351. data/test/models/company.rb +228 -225
  352. data/test/models/company_in_module.rb +98 -98
  353. data/test/models/computer.rb +3 -3
  354. data/test/models/contact.rb +41 -41
  355. data/test/models/contract.rb +20 -20
  356. data/test/models/country.rb +7 -7
  357. data/test/models/course.rb +6 -6
  358. data/test/models/customer.rb +77 -77
  359. data/test/models/customer_carrier.rb +14 -14
  360. data/test/models/dashboard.rb +3 -3
  361. data/test/models/default.rb +2 -2
  362. data/test/models/department.rb +4 -4
  363. data/test/models/developer.rb +255 -252
  364. data/test/models/dog.rb +5 -5
  365. data/test/models/dog_lover.rb +5 -5
  366. data/test/models/doubloon.rb +12 -12
  367. data/test/models/drink_designer.rb +3 -3
  368. data/test/models/edge.rb +5 -5
  369. data/test/models/electron.rb +5 -5
  370. data/test/models/engine.rb +4 -4
  371. data/test/models/entrant.rb +3 -3
  372. data/test/models/essay.rb +5 -5
  373. data/test/models/event.rb +2 -2
  374. data/test/models/eye.rb +37 -37
  375. data/test/models/face.rb +9 -9
  376. data/test/models/friendship.rb +6 -6
  377. data/test/models/guid.rb +1 -1
  378. data/test/models/hotel.rb +9 -6
  379. data/test/models/image.rb +3 -3
  380. data/test/models/interest.rb +5 -5
  381. data/test/models/invoice.rb +4 -4
  382. data/test/models/item.rb +7 -7
  383. data/test/models/job.rb +7 -7
  384. data/test/models/joke.rb +7 -7
  385. data/test/models/keyboard.rb +3 -3
  386. data/test/models/legacy_thing.rb +3 -3
  387. data/test/models/lesson.rb +11 -11
  388. data/test/models/line_item.rb +3 -3
  389. data/test/models/liquid.rb +4 -4
  390. data/test/models/man.rb +11 -11
  391. data/test/models/matey.rb +4 -4
  392. data/test/models/member.rb +41 -41
  393. data/test/models/member_detail.rb +7 -7
  394. data/test/models/member_type.rb +3 -3
  395. data/test/models/membership.rb +35 -35
  396. data/test/models/minimalistic.rb +2 -2
  397. data/test/models/minivan.rb +9 -9
  398. data/test/models/mixed_case_monkey.rb +3 -3
  399. data/test/models/molecule.rb +6 -6
  400. data/test/models/movie.rb +5 -5
  401. data/test/models/order.rb +4 -4
  402. data/test/models/organization.rb +14 -14
  403. data/test/models/owner.rb +34 -34
  404. data/test/models/parrot.rb +29 -29
  405. data/test/models/person.rb +143 -143
  406. data/test/models/personal_legacy_thing.rb +4 -4
  407. data/test/models/pet.rb +15 -15
  408. data/test/models/pirate.rb +92 -92
  409. data/test/models/possession.rb +3 -3
  410. data/test/models/post.rb +264 -264
  411. data/test/models/price_estimate.rb +4 -4
  412. data/test/models/professor.rb +5 -5
  413. data/test/models/project.rb +31 -29
  414. data/test/models/publisher.rb +2 -2
  415. data/test/models/publisher/article.rb +4 -4
  416. data/test/models/publisher/magazine.rb +3 -3
  417. data/test/models/randomly_named_c1.rb +3 -3
  418. data/test/models/rating.rb +4 -4
  419. data/test/models/reader.rb +23 -23
  420. data/test/models/record.rb +2 -2
  421. data/test/models/reference.rb +22 -22
  422. data/test/models/reply.rb +61 -61
  423. data/test/models/ship.rb +33 -33
  424. data/test/models/ship_part.rb +7 -7
  425. data/test/models/shop.rb +17 -17
  426. data/test/models/shop_account.rb +6 -6
  427. data/test/models/speedometer.rb +6 -6
  428. data/test/models/sponsor.rb +7 -7
  429. data/test/models/string_key_object.rb +3 -3
  430. data/test/models/student.rb +4 -4
  431. data/test/models/subject.rb +16 -16
  432. data/test/models/subscriber.rb +8 -8
  433. data/test/models/subscription.rb +4 -4
  434. data/test/models/tag.rb +7 -7
  435. data/test/models/tagging.rb +13 -13
  436. data/test/models/task.rb +5 -5
  437. data/test/models/topic.rb +124 -124
  438. data/test/models/toy.rb +6 -6
  439. data/test/models/traffic_light.rb +4 -4
  440. data/test/models/treasure.rb +14 -14
  441. data/test/models/treaty.rb +7 -7
  442. data/test/models/tyre.rb +11 -11
  443. data/test/models/uuid_child.rb +3 -3
  444. data/test/models/uuid_parent.rb +3 -3
  445. data/test/models/vegetables.rb +24 -24
  446. data/test/models/vehicle.rb +6 -6
  447. data/test/models/vertex.rb +9 -9
  448. data/test/models/warehouse_thing.rb +5 -5
  449. data/test/models/wheel.rb +3 -3
  450. data/test/models/without_table.rb +3 -3
  451. data/test/models/zine.rb +3 -3
  452. data/test/schema/mysql2_specific_schema.rb +58 -58
  453. data/test/schema/mysql_specific_schema.rb +70 -70
  454. data/test/schema/oracle_specific_schema.rb +43 -43
  455. data/test/schema/postgresql_specific_schema.rb +202 -202
  456. data/test/schema/schema.rb +952 -938
  457. data/test/schema/sqlite_specific_schema.rb +21 -21
  458. data/test/support/config.rb +43 -43
  459. data/test/support/connection.rb +22 -22
  460. data/test/support/connection_helper.rb +14 -14
  461. data/test/support/ddl_helper.rb +8 -8
  462. data/test/support/schema_dumping_helper.rb +20 -20
  463. metadata +2 -2
@@ -1,754 +1,754 @@
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_fixtures = false unless supports_savepoints?
21
-
22
- fixtures :posts, :authors, :categories, :categorizations, :comments, :tags, :taggings, :author_favorites, :vertices, :items, :books, :author_addresses,
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_uniq_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_uniq_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_uniq_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(NoMethodError) { 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
- assert_nil posts(:welcome).tagging(true)
217
- end
218
-
219
- def test_delete_polymorphic_has_one_with_nullify
220
- assert posts(:welcome).tagging
221
- posts(:welcome).tagging.update_columns taggable_type: 'PostWithHasOneNullify'
222
- post = find_post_with_dependency(1, :has_one, :tagging, :nullify)
223
-
224
- old_count = Tagging.count
225
- post.destroy
226
- assert_equal old_count, Tagging.count
227
- assert_nil posts(:welcome).tagging(true)
228
- end
229
-
230
- def test_has_many_with_piggyback
231
- assert_equal "2", categories(:sti_test).authors_with_select.first.post_id.to_s
232
- end
233
-
234
- def test_create_through_has_many_with_piggyback
235
- category = categories(:sti_test)
236
- ernie = category.authors_with_select.create(:name => 'Ernie')
237
- assert_nothing_raised do
238
- assert_equal ernie, category.authors_with_select.detect {|a| a.name == 'Ernie'}
239
- end
240
- end
241
-
242
- def test_include_has_many_through
243
- posts = Post.all.merge!(:order => 'posts.id').to_a
244
- posts_with_authors = Post.all.merge!(:includes => :authors, :order => 'posts.id').to_a
245
- assert_equal posts.length, posts_with_authors.length
246
- posts.length.times do |i|
247
- assert_equal posts[i].authors.length, assert_no_queries { posts_with_authors[i].authors.length }
248
- end
249
- end
250
-
251
- def test_include_polymorphic_has_one
252
- post = Post.includes(:tagging).find posts(:welcome).id
253
- tagging = taggings(:welcome_general)
254
- assert_no_queries do
255
- assert_equal tagging, post.tagging
256
- end
257
- end
258
-
259
- def test_include_polymorphic_has_one_defined_in_abstract_parent
260
- item = Item.includes(:tagging).find items(:dvd).id
261
- tagging = taggings(:godfather)
262
- assert_no_queries do
263
- assert_equal tagging, item.tagging
264
- end
265
- end
266
-
267
- def test_include_polymorphic_has_many_through
268
- posts = Post.all.merge!(:order => 'posts.id').to_a
269
- posts_with_tags = Post.all.merge!(:includes => :tags, :order => 'posts.id').to_a
270
- assert_equal posts.length, posts_with_tags.length
271
- posts.length.times do |i|
272
- assert_equal posts[i].tags.length, assert_no_queries { posts_with_tags[i].tags.length }
273
- end
274
- end
275
-
276
- def test_include_polymorphic_has_many
277
- posts = Post.all.merge!(:order => 'posts.id').to_a
278
- posts_with_taggings = Post.all.merge!(:includes => :taggings, :order => 'posts.id').to_a
279
- assert_equal posts.length, posts_with_taggings.length
280
- posts.length.times do |i|
281
- assert_equal posts[i].taggings.length, assert_no_queries { posts_with_taggings[i].taggings.length }
282
- end
283
- end
284
-
285
- def test_has_many_find_all
286
- assert_equal [categories(:general)], authors(:david).categories.to_a
287
- end
288
-
289
- def test_has_many_find_first
290
- assert_equal categories(:general), authors(:david).categories.first
291
- end
292
-
293
- def test_has_many_with_hash_conditions
294
- assert_equal categories(:general), authors(:david).categories_like_general.first
295
- end
296
-
297
- def test_has_many_find_conditions
298
- assert_equal categories(:general), authors(:david).categories.where("categories.name = 'General'").first
299
- assert_nil authors(:david).categories.where("categories.name = 'Technology'").first
300
- end
301
-
302
- def test_has_many_array_methods_called_by_method_missing
303
- assert authors(:david).categories.any? { |category| category.name == 'General' }
304
- assert_nothing_raised { authors(:david).categories.sort }
305
- end
306
-
307
- def test_has_many_going_through_join_model_with_custom_foreign_key
308
- assert_equal [authors(:bob)], posts(:thinking).authors
309
- assert_equal [authors(:mary)], posts(:authorless).authors
310
- end
311
-
312
- def test_has_many_going_through_join_model_with_custom_primary_key
313
- assert_equal [authors(:david)], posts(:thinking).authors_using_author_id
314
- end
315
-
316
- def test_has_many_going_through_polymorphic_join_model_with_custom_primary_key
317
- assert_equal [tags(:general)], posts(:eager_other).tags_using_author_id
318
- end
319
-
320
- def test_has_many_through_with_custom_primary_key_on_belongs_to_source
321
- assert_equal [authors(:david), authors(:david)], posts(:thinking).author_using_custom_pk
322
- end
323
-
324
- def test_has_many_through_with_custom_primary_key_on_has_many_source
325
- assert_equal [authors(:david), authors(:bob)], posts(:thinking).authors_using_custom_pk.order('authors.id')
326
- end
327
-
328
- def test_belongs_to_polymorphic_with_counter_cache
329
- assert_equal 1, posts(:welcome)[:tags_count]
330
- tagging = posts(:welcome).taggings.create(:tag => tags(:general))
331
- assert_equal 2, posts(:welcome, :reload)[:tags_count]
332
- tagging.destroy
333
- assert_equal 1, posts(:welcome, :reload)[:tags_count]
334
- end
335
-
336
- def test_unavailable_through_reflection
337
- assert_raise(ActiveRecord::HasManyThroughAssociationNotFoundError) { authors(:david).nothings }
338
- end
339
-
340
- def test_has_many_through_join_model_with_conditions
341
- assert_equal [], posts(:welcome).invalid_taggings
342
- assert_equal [], posts(:welcome).invalid_tags
343
- end
344
-
345
- def test_has_many_polymorphic
346
- assert_raise ActiveRecord::HasManyThroughAssociationPolymorphicSourceError do
347
- tags(:general).taggables
348
- end
349
-
350
- assert_raise ActiveRecord::HasManyThroughAssociationPolymorphicThroughError do
351
- taggings(:welcome_general).things
352
- end
353
-
354
- assert_raise ActiveRecord::EagerLoadPolymorphicError do
355
- tags(:general).taggings.includes(:taggable).where('bogus_table.column = 1').references(:bogus_table).to_a
356
- end
357
- end
358
-
359
- def test_has_many_polymorphic_with_source_type
360
- # added sort by ID as otherwise Oracle select sometimes returned rows in different order
361
- assert_equal posts(:welcome, :thinking).sort_by(&:id), tags(:general).tagged_posts.sort_by(&:id)
362
- end
363
-
364
- def test_eager_has_many_polymorphic_with_source_type
365
- tag_with_include = Tag.all.merge!(:includes => :tagged_posts).find(tags(:general).id)
366
- desired = posts(:welcome, :thinking)
367
- assert_no_queries do
368
- # added sort by ID as otherwise test using JRuby was failing as array elements were in different order
369
- assert_equal desired.sort_by(&:id), tag_with_include.tagged_posts.sort_by(&:id)
370
- end
371
- assert_equal 5, tag_with_include.taggings.length
372
- end
373
-
374
- def test_has_many_through_has_many_find_all
375
- assert_equal comments(:greetings), authors(:david).comments.order('comments.id').to_a.first
376
- end
377
-
378
- def test_has_many_through_has_many_find_all_with_custom_class
379
- assert_equal comments(:greetings), authors(:david).funky_comments.order('comments.id').to_a.first
380
- end
381
-
382
- def test_has_many_through_has_many_find_first
383
- assert_equal comments(:greetings), authors(:david).comments.order('comments.id').first
384
- end
385
-
386
- def test_has_many_through_has_many_find_conditions
387
- options = { :where => "comments.#{QUOTED_TYPE}='SpecialComment'", :order => 'comments.id' }
388
- assert_equal comments(:does_it_hurt), authors(:david).comments.merge(options).first
389
- end
390
-
391
- def test_has_many_through_has_many_find_by_id
392
- assert_equal comments(:more_greetings), authors(:david).comments.find(2)
393
- end
394
-
395
- def test_has_many_through_polymorphic_has_one
396
- assert_equal Tagging.find(1,2).sort_by { |t| t.id }, authors(:david).taggings_2
397
- end
398
-
399
- def test_has_many_through_polymorphic_has_many
400
- assert_equal taggings(:welcome_general, :thinking_general), authors(:david).taggings.distinct.sort_by { |t| t.id }
401
- end
402
-
403
- def test_include_has_many_through_polymorphic_has_many
404
- author = Author.includes(:taggings).find authors(:david).id
405
- expected_taggings = taggings(:welcome_general, :thinking_general)
406
- assert_no_queries do
407
- assert_equal expected_taggings, author.taggings.distinct.sort_by { |t| t.id }
408
- end
409
- end
410
-
411
- unless current_adapter?(:IBM_DBAdapter)
412
- # DB2 throws SQL0214N
413
- def test_eager_load_has_many_through_has_many
414
- author = Author.all.merge!(:where => ['name = ?', 'David'], :includes => :comments, :order => 'comments.id').first
415
- SpecialComment.new; VerySpecialComment.new
416
- assert_no_queries do
417
- assert_equal [1,2,3,5,6,7,8,9,10,12], author.comments.collect(&:id)
418
- end
419
- end
420
- end
421
-
422
- def test_eager_load_has_many_through_has_many_with_conditions
423
- post = Post.all.merge!(:includes => :invalid_tags).first
424
- assert_no_queries do
425
- post.invalid_tags
426
- end
427
- end
428
-
429
- def test_eager_belongs_to_and_has_one_not_singularized
430
- assert_nothing_raised do
431
- Author.all.merge!(:includes => :author_address).first
432
- AuthorAddress.all.merge!(:includes => :author).first
433
- end
434
- end
435
-
436
- def test_self_referential_has_many_through
437
- assert_equal [authors(:mary)], authors(:david).favorite_authors
438
- assert_equal [], authors(:mary).favorite_authors
439
- end
440
-
441
- def test_add_to_self_referential_has_many_through
442
- new_author = Author.create(:name => "Bob")
443
- authors(:david).author_favorites.create :favorite_author => new_author
444
- assert_equal new_author, authors(:david).reload.favorite_authors.first
445
- end
446
-
447
- def test_has_many_through_uses_conditions_specified_on_the_has_many_association
448
- author = Author.first
449
- assert author.comments.present?
450
- assert author.nonexistant_comments.blank?
451
- end
452
-
453
- def test_has_many_through_uses_correct_attributes
454
- assert_nil posts(:thinking).tags.find_by_name("General").attributes["tag_id"]
455
- end
456
-
457
- def test_associating_unsaved_records_with_has_many_through
458
- saved_post = posts(:thinking)
459
- new_tag = Tag.new(:name => "new")
460
-
461
- saved_post.tags << new_tag
462
- assert new_tag.persisted? #consistent with habtm!
463
- assert saved_post.persisted?
464
- assert saved_post.tags.include?(new_tag)
465
-
466
- assert new_tag.persisted?
467
- assert saved_post.reload.tags(true).include?(new_tag)
468
-
469
-
470
- new_post = Post.new(:title => "Association replacement works!", :body => "You best believe it.")
471
- saved_tag = tags(:general)
472
-
473
- new_post.tags << saved_tag
474
- assert !new_post.persisted?
475
- assert saved_tag.persisted?
476
- assert new_post.tags.include?(saved_tag)
477
-
478
- new_post.save!
479
- assert new_post.persisted?
480
- assert new_post.reload.tags(true).include?(saved_tag)
481
-
482
- assert !posts(:thinking).tags.build.persisted?
483
- assert !posts(:thinking).tags.new.persisted?
484
- end
485
-
486
- def test_create_associate_when_adding_to_has_many_through
487
- count = posts(:thinking).tags.count
488
- push = Tag.create!(:name => 'pushme')
489
- post_thinking = posts(:thinking)
490
- assert_nothing_raised { post_thinking.tags << push }
491
- assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
492
- message = "Expected a Tag in tags collection, got #{wrong.class}.")
493
- assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
494
- message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
495
- assert_equal(count + 1, post_thinking.reload.tags.size)
496
- assert_equal(count + 1, post_thinking.tags(true).size)
497
-
498
- assert_kind_of Tag, post_thinking.tags.create!(:name => 'foo')
499
- assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
500
- message = "Expected a Tag in tags collection, got #{wrong.class}.")
501
- assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
502
- message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
503
- assert_equal(count + 2, post_thinking.reload.tags.size)
504
- assert_equal(count + 2, post_thinking.tags(true).size)
505
-
506
- assert_nothing_raised { post_thinking.tags.concat(Tag.create!(:name => 'abc'), Tag.create!(:name => 'def')) }
507
- assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
508
- message = "Expected a Tag in tags collection, got #{wrong.class}.")
509
- assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
510
- message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
511
- assert_equal(count + 4, post_thinking.reload.tags.size)
512
- assert_equal(count + 4, post_thinking.tags(true).size)
513
-
514
- # Raises if the wrong reflection name is used to set the Edge belongs_to
515
- assert_nothing_raised { vertices(:vertex_1).sinks << vertices(:vertex_5) }
516
- end
517
-
518
- def test_add_to_join_table_with_no_id
519
- assert_nothing_raised { vertices(:vertex_1).sinks << vertices(:vertex_5) }
520
- end
521
-
522
- def test_has_many_through_collection_size_doesnt_load_target_if_not_loaded
523
- author = authors(:david)
524
- assert_equal 10, author.comments.size
525
- assert !author.comments.loaded?
526
- end
527
-
528
- def test_has_many_through_collection_size_uses_counter_cache_if_it_exists
529
- c = categories(:general)
530
- c.categorizations_count = 100
531
- assert_equal 100, c.categorizations.size
532
- assert !c.categorizations.loaded?
533
- end
534
-
535
- def test_adding_junk_to_has_many_through_should_raise_type_mismatch
536
- assert_raise(ActiveRecord::AssociationTypeMismatch) { posts(:thinking).tags << "Uhh what now?" }
537
- end
538
-
539
- def test_adding_to_has_many_through_should_return_self
540
- tags = posts(:thinking).tags
541
- assert_equal tags, posts(:thinking).tags.push(tags(:general))
542
- end
543
-
544
- def test_delete_associate_when_deleting_from_has_many_through_with_nonstandard_id
545
- count = books(:awdr).references.count
546
- references_before = books(:awdr).references
547
- book = Book.create!(:name => 'Getting Real')
548
- book_awdr = books(:awdr)
549
- book_awdr.references << book
550
- assert_equal(count + 1, book_awdr.references(true).size)
551
-
552
- assert_nothing_raised { book_awdr.references.delete(book) }
553
- assert_equal(count, book_awdr.references.size)
554
- assert_equal(count, book_awdr.references(true).size)
555
- assert_equal(references_before.sort, book_awdr.references.sort)
556
- end
557
-
558
- def test_delete_associate_when_deleting_from_has_many_through
559
- count = posts(:thinking).tags.count
560
- tags_before = posts(:thinking).tags.sort
561
- tag = Tag.create!(:name => 'doomed')
562
- post_thinking = posts(:thinking)
563
- post_thinking.tags << tag
564
- assert_equal(count + 1, post_thinking.taggings(true).size)
565
- assert_equal(count + 1, post_thinking.reload.tags(true).size)
566
- assert_not_equal(tags_before, post_thinking.tags.sort)
567
-
568
- assert_nothing_raised { post_thinking.tags.delete(tag) }
569
- assert_equal(count, post_thinking.tags.size)
570
- assert_equal(count, post_thinking.tags(true).size)
571
- assert_equal(count, post_thinking.taggings(true).size)
572
- assert_equal(tags_before, post_thinking.tags.sort)
573
- end
574
-
575
- def test_delete_associate_when_deleting_from_has_many_through_with_multiple_tags
576
- count = posts(:thinking).tags.count
577
- tags_before = posts(:thinking).tags.sort
578
- doomed = Tag.create!(:name => 'doomed')
579
- doomed2 = Tag.create!(:name => 'doomed2')
580
- quaked = Tag.create!(:name => 'quaked')
581
- post_thinking = posts(:thinking)
582
- post_thinking.tags << doomed << doomed2
583
- assert_equal(count + 2, post_thinking.reload.tags(true).size)
584
-
585
- assert_nothing_raised { post_thinking.tags.delete(doomed, doomed2, quaked) }
586
- assert_equal(count, post_thinking.tags.size)
587
- assert_equal(count, post_thinking.tags(true).size)
588
- assert_equal(tags_before, post_thinking.tags.sort)
589
- end
590
-
591
- def test_deleting_junk_from_has_many_through_should_raise_type_mismatch
592
- assert_raise(ActiveRecord::AssociationTypeMismatch) { posts(:thinking).tags.delete(Object.new) }
593
- end
594
-
595
- def test_deleting_by_fixnum_id_from_has_many_through
596
- post = posts(:thinking)
597
-
598
- assert_difference 'post.tags.count', -1 do
599
- assert_equal 1, post.tags.delete(1).size
600
- end
601
-
602
- assert_equal 0, post.tags.size
603
- end
604
-
605
- def test_deleting_by_string_id_from_has_many_through
606
- post = posts(:thinking)
607
-
608
- assert_difference 'post.tags.count', -1 do
609
- assert_equal 1, post.tags.delete('1').size
610
- end
611
-
612
- assert_equal 0, post.tags.size
613
- end
614
-
615
- def test_has_many_through_sum_uses_calculations
616
- assert_nothing_raised { authors(:david).comments.sum(:post_id) }
617
- end
618
-
619
- def test_calculations_on_has_many_through_should_disambiguate_fields
620
- assert_nothing_raised { authors(:david).categories.maximum(:id) }
621
- end
622
-
623
- def test_calculations_on_has_many_through_should_not_disambiguate_fields_unless_necessary
624
- assert_nothing_raised { authors(:david).categories.maximum("categories.id") }
625
- end
626
-
627
- def test_has_many_through_has_many_with_sti
628
- assert_equal [comments(:does_it_hurt)], authors(:david).special_post_comments
629
- end
630
-
631
- def test_uniq_has_many_through_should_retain_order
632
- comment_ids = authors(:david).comments.map(&:id)
633
- assert_equal comment_ids.sort, authors(:david).ordered_uniq_comments.map(&:id)
634
- assert_equal comment_ids.sort.reverse, authors(:david).ordered_uniq_comments_desc.map(&:id)
635
- end
636
-
637
- def test_polymorphic_has_many
638
- expected = taggings(:welcome_general)
639
- p = Post.all.merge!(:includes => :taggings).find(posts(:welcome).id)
640
- assert_no_queries {assert p.taggings.include?(expected)}
641
- assert posts(:welcome).taggings.include?(taggings(:welcome_general))
642
- end
643
-
644
- def test_polymorphic_has_one
645
- expected = posts(:welcome)
646
-
647
- tagging = Tagging.all.merge!(:includes => :taggable).find(taggings(:welcome_general).id)
648
- assert_no_queries { assert_equal expected, tagging.taggable}
649
- end
650
-
651
- def test_polymorphic_belongs_to
652
- p = Post.all.merge!(:includes => {:taggings => :taggable}).find(posts(:welcome).id)
653
- assert_no_queries {assert_equal posts(:welcome), p.taggings.first.taggable}
654
- end
655
-
656
- def test_preload_polymorphic_has_many_through
657
- posts = Post.all.merge!(:order => 'posts.id').to_a
658
- posts_with_tags = Post.all.merge!(:includes => :tags, :order => 'posts.id').to_a
659
- assert_equal posts.length, posts_with_tags.length
660
- posts.length.times do |i|
661
- assert_equal posts[i].tags.length, assert_no_queries { posts_with_tags[i].tags.length }
662
- end
663
- end
664
-
665
- def test_preload_polymorph_many_types
666
- taggings = Tagging.all.merge!(:includes => :taggable, :where => ['taggable_type != ?', 'FakeModel']).to_a
667
- assert_no_queries do
668
- taggings.first.taggable.id
669
- taggings[1].taggable.id
670
- end
671
-
672
- taggables = taggings.map(&:taggable)
673
- assert taggables.include?(items(:dvd))
674
- assert taggables.include?(posts(:welcome))
675
- end
676
-
677
- def test_preload_nil_polymorphic_belongs_to
678
- assert_nothing_raised do
679
- Tagging.all.merge!(:includes => :taggable, :where => ['taggable_type IS NULL']).to_a
680
- end
681
- end
682
-
683
- def test_preload_polymorphic_has_many
684
- posts = Post.all.merge!(:order => 'posts.id').to_a
685
- posts_with_taggings = Post.all.merge!(:includes => :taggings, :order => 'posts.id').to_a
686
- assert_equal posts.length, posts_with_taggings.length
687
- posts.length.times do |i|
688
- assert_equal posts[i].taggings.length, assert_no_queries { posts_with_taggings[i].taggings.length }
689
- end
690
- end
691
-
692
- def test_belongs_to_shared_parent
693
- comments = Comment.all.merge!(:includes => :post, :where => 'post_id = 1').to_a
694
- assert_no_queries do
695
- assert_equal comments.first.post, comments[1].post
696
- end
697
- end
698
-
699
- def test_has_many_through_include_uses_array_include_after_loaded
700
- david = authors(:david)
701
- david.categories.load_target
702
-
703
- category = david.categories.first
704
-
705
- assert_no_queries do
706
- assert david.categories.loaded?
707
- assert david.categories.include?(category)
708
- end
709
- end
710
-
711
- def test_has_many_through_include_checks_if_record_exists_if_target_not_loaded
712
- david = authors(:david)
713
- category = david.categories.first
714
-
715
- david.reload
716
- assert ! david.categories.loaded?
717
- assert_queries(1) do
718
- assert david.categories.include?(category)
719
- end
720
- assert ! david.categories.loaded?
721
- end
722
-
723
- def test_has_many_through_include_returns_false_for_non_matching_record_to_verify_scoping
724
- david = authors(:david)
725
- category = Category.create!(:name => 'Not Associated')
726
-
727
- assert ! david.categories.loaded?
728
- assert ! david.categories.include?(category)
729
- end
730
-
731
- def test_has_many_through_goes_through_all_sti_classes
732
- sub_sti_post = SubStiPost.create!(:title => 'test', :body => 'test', :author_id => 1)
733
- new_comment = sub_sti_post.comments.create(:body => 'test')
734
-
735
- assert_equal [9, 10, new_comment.id], authors(:david).sti_post_comments.map(&:id).sort
736
- end
737
-
738
- def test_has_many_with_pluralize_table_names_false
739
- aircraft = Aircraft.create!(:name => "Airbus 380")
740
- engine = Engine.create!(:car_id => aircraft.id)
741
- assert_equal aircraft.engines, [engine]
742
- end
743
-
744
- private
745
- # create dynamic Post models to allow different dependency options
746
- def find_post_with_dependency(post_id, association, association_name, dependency)
747
- class_name = "PostWith#{association.to_s.classify}#{dependency.to_s.classify}"
748
- Post.find(post_id).update_columns type: class_name
749
- klass = Object.const_set(class_name, Class.new(ActiveRecord::Base))
750
- klass.table_name = 'posts'
751
- klass.send(association, association_name, :as => :taggable, :dependent => dependency)
752
- klass.find(post_id)
753
- end
754
- 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_fixtures = false unless supports_savepoints?
21
+
22
+ fixtures :posts, :authors, :categories, :categorizations, :comments, :tags, :taggings, :author_favorites, :vertices, :items, :books, :author_addresses,
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_uniq_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_uniq_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_uniq_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(NoMethodError) { 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
+ assert_nil posts(:welcome).tagging(true)
217
+ end
218
+
219
+ def test_delete_polymorphic_has_one_with_nullify
220
+ assert posts(:welcome).tagging
221
+ posts(:welcome).tagging.update_columns taggable_type: 'PostWithHasOneNullify'
222
+ post = find_post_with_dependency(1, :has_one, :tagging, :nullify)
223
+
224
+ old_count = Tagging.count
225
+ post.destroy
226
+ assert_equal old_count, Tagging.count
227
+ assert_nil posts(:welcome).tagging(true)
228
+ end
229
+
230
+ def test_has_many_with_piggyback
231
+ assert_equal "2", categories(:sti_test).authors_with_select.first.post_id.to_s
232
+ end
233
+
234
+ def test_create_through_has_many_with_piggyback
235
+ category = categories(:sti_test)
236
+ ernie = category.authors_with_select.create(:name => 'Ernie')
237
+ assert_nothing_raised do
238
+ assert_equal ernie, category.authors_with_select.detect {|a| a.name == 'Ernie'}
239
+ end
240
+ end
241
+
242
+ def test_include_has_many_through
243
+ posts = Post.all.merge!(:order => 'posts.id').to_a
244
+ posts_with_authors = Post.all.merge!(:includes => :authors, :order => 'posts.id').to_a
245
+ assert_equal posts.length, posts_with_authors.length
246
+ posts.length.times do |i|
247
+ assert_equal posts[i].authors.length, assert_no_queries { posts_with_authors[i].authors.length }
248
+ end
249
+ end
250
+
251
+ def test_include_polymorphic_has_one
252
+ post = Post.includes(:tagging).find posts(:welcome).id
253
+ tagging = taggings(:welcome_general)
254
+ assert_no_queries do
255
+ assert_equal tagging, post.tagging
256
+ end
257
+ end
258
+
259
+ def test_include_polymorphic_has_one_defined_in_abstract_parent
260
+ item = Item.includes(:tagging).find items(:dvd).id
261
+ tagging = taggings(:godfather)
262
+ assert_no_queries do
263
+ assert_equal tagging, item.tagging
264
+ end
265
+ end
266
+
267
+ def test_include_polymorphic_has_many_through
268
+ posts = Post.all.merge!(:order => 'posts.id').to_a
269
+ posts_with_tags = Post.all.merge!(:includes => :tags, :order => 'posts.id').to_a
270
+ assert_equal posts.length, posts_with_tags.length
271
+ posts.length.times do |i|
272
+ assert_equal posts[i].tags.length, assert_no_queries { posts_with_tags[i].tags.length }
273
+ end
274
+ end
275
+
276
+ def test_include_polymorphic_has_many
277
+ posts = Post.all.merge!(:order => 'posts.id').to_a
278
+ posts_with_taggings = Post.all.merge!(:includes => :taggings, :order => 'posts.id').to_a
279
+ assert_equal posts.length, posts_with_taggings.length
280
+ posts.length.times do |i|
281
+ assert_equal posts[i].taggings.length, assert_no_queries { posts_with_taggings[i].taggings.length }
282
+ end
283
+ end
284
+
285
+ def test_has_many_find_all
286
+ assert_equal [categories(:general)], authors(:david).categories.to_a
287
+ end
288
+
289
+ def test_has_many_find_first
290
+ assert_equal categories(:general), authors(:david).categories.first
291
+ end
292
+
293
+ def test_has_many_with_hash_conditions
294
+ assert_equal categories(:general), authors(:david).categories_like_general.first
295
+ end
296
+
297
+ def test_has_many_find_conditions
298
+ assert_equal categories(:general), authors(:david).categories.where("categories.name = 'General'").first
299
+ assert_nil authors(:david).categories.where("categories.name = 'Technology'").first
300
+ end
301
+
302
+ def test_has_many_array_methods_called_by_method_missing
303
+ assert authors(:david).categories.any? { |category| category.name == 'General' }
304
+ assert_nothing_raised { authors(:david).categories.sort }
305
+ end
306
+
307
+ def test_has_many_going_through_join_model_with_custom_foreign_key
308
+ assert_equal [authors(:bob)], posts(:thinking).authors
309
+ assert_equal [authors(:mary)], posts(:authorless).authors
310
+ end
311
+
312
+ def test_has_many_going_through_join_model_with_custom_primary_key
313
+ assert_equal [authors(:david)], posts(:thinking).authors_using_author_id
314
+ end
315
+
316
+ def test_has_many_going_through_polymorphic_join_model_with_custom_primary_key
317
+ assert_equal [tags(:general)], posts(:eager_other).tags_using_author_id
318
+ end
319
+
320
+ def test_has_many_through_with_custom_primary_key_on_belongs_to_source
321
+ assert_equal [authors(:david), authors(:david)], posts(:thinking).author_using_custom_pk
322
+ end
323
+
324
+ def test_has_many_through_with_custom_primary_key_on_has_many_source
325
+ assert_equal [authors(:david), authors(:bob)], posts(:thinking).authors_using_custom_pk.order('authors.id')
326
+ end
327
+
328
+ def test_belongs_to_polymorphic_with_counter_cache
329
+ assert_equal 1, posts(:welcome)[:tags_count]
330
+ tagging = posts(:welcome).taggings.create(:tag => tags(:general))
331
+ assert_equal 2, posts(:welcome, :reload)[:tags_count]
332
+ tagging.destroy
333
+ assert_equal 1, posts(:welcome, :reload)[:tags_count]
334
+ end
335
+
336
+ def test_unavailable_through_reflection
337
+ assert_raise(ActiveRecord::HasManyThroughAssociationNotFoundError) { authors(:david).nothings }
338
+ end
339
+
340
+ def test_has_many_through_join_model_with_conditions
341
+ assert_equal [], posts(:welcome).invalid_taggings
342
+ assert_equal [], posts(:welcome).invalid_tags
343
+ end
344
+
345
+ def test_has_many_polymorphic
346
+ assert_raise ActiveRecord::HasManyThroughAssociationPolymorphicSourceError do
347
+ tags(:general).taggables
348
+ end
349
+
350
+ assert_raise ActiveRecord::HasManyThroughAssociationPolymorphicThroughError do
351
+ taggings(:welcome_general).things
352
+ end
353
+
354
+ assert_raise ActiveRecord::EagerLoadPolymorphicError do
355
+ tags(:general).taggings.includes(:taggable).where('bogus_table.column = 1').references(:bogus_table).to_a
356
+ end
357
+ end
358
+
359
+ def test_has_many_polymorphic_with_source_type
360
+ # added sort by ID as otherwise Oracle select sometimes returned rows in different order
361
+ assert_equal posts(:welcome, :thinking).sort_by(&:id), tags(:general).tagged_posts.sort_by(&:id)
362
+ end
363
+
364
+ def test_eager_has_many_polymorphic_with_source_type
365
+ tag_with_include = Tag.all.merge!(:includes => :tagged_posts).find(tags(:general).id)
366
+ desired = posts(:welcome, :thinking)
367
+ assert_no_queries do
368
+ # added sort by ID as otherwise test using JRuby was failing as array elements were in different order
369
+ assert_equal desired.sort_by(&:id), tag_with_include.tagged_posts.sort_by(&:id)
370
+ end
371
+ assert_equal 5, tag_with_include.taggings.length
372
+ end
373
+
374
+ def test_has_many_through_has_many_find_all
375
+ assert_equal comments(:greetings), authors(:david).comments.order('comments.id').to_a.first
376
+ end
377
+
378
+ def test_has_many_through_has_many_find_all_with_custom_class
379
+ assert_equal comments(:greetings), authors(:david).funky_comments.order('comments.id').to_a.first
380
+ end
381
+
382
+ def test_has_many_through_has_many_find_first
383
+ assert_equal comments(:greetings), authors(:david).comments.order('comments.id').first
384
+ end
385
+
386
+ def test_has_many_through_has_many_find_conditions
387
+ options = { :where => "comments.#{QUOTED_TYPE}='SpecialComment'", :order => 'comments.id' }
388
+ assert_equal comments(:does_it_hurt), authors(:david).comments.merge(options).first
389
+ end
390
+
391
+ def test_has_many_through_has_many_find_by_id
392
+ assert_equal comments(:more_greetings), authors(:david).comments.find(2)
393
+ end
394
+
395
+ def test_has_many_through_polymorphic_has_one
396
+ assert_equal Tagging.find(1,2).sort_by { |t| t.id }, authors(:david).taggings_2
397
+ end
398
+
399
+ def test_has_many_through_polymorphic_has_many
400
+ assert_equal taggings(:welcome_general, :thinking_general), authors(:david).taggings.distinct.sort_by { |t| t.id }
401
+ end
402
+
403
+ def test_include_has_many_through_polymorphic_has_many
404
+ author = Author.includes(:taggings).find authors(:david).id
405
+ expected_taggings = taggings(:welcome_general, :thinking_general)
406
+ assert_no_queries do
407
+ assert_equal expected_taggings, author.taggings.distinct.sort_by { |t| t.id }
408
+ end
409
+ end
410
+
411
+ unless current_adapter?(:IBM_DBAdapter)
412
+ # DB2 throws SQL0214N
413
+ def test_eager_load_has_many_through_has_many
414
+ author = Author.all.merge!(:where => ['name = ?', 'David'], :includes => :comments, :order => 'comments.id').first
415
+ SpecialComment.new; VerySpecialComment.new
416
+ assert_no_queries do
417
+ assert_equal [1,2,3,5,6,7,8,9,10,12], author.comments.collect(&:id)
418
+ end
419
+ end
420
+ end
421
+
422
+ def test_eager_load_has_many_through_has_many_with_conditions
423
+ post = Post.all.merge!(:includes => :invalid_tags).first
424
+ assert_no_queries do
425
+ post.invalid_tags
426
+ end
427
+ end
428
+
429
+ def test_eager_belongs_to_and_has_one_not_singularized
430
+ assert_nothing_raised do
431
+ Author.all.merge!(:includes => :author_address).first
432
+ AuthorAddress.all.merge!(:includes => :author).first
433
+ end
434
+ end
435
+
436
+ def test_self_referential_has_many_through
437
+ assert_equal [authors(:mary)], authors(:david).favorite_authors
438
+ assert_equal [], authors(:mary).favorite_authors
439
+ end
440
+
441
+ def test_add_to_self_referential_has_many_through
442
+ new_author = Author.create(:name => "Bob")
443
+ authors(:david).author_favorites.create :favorite_author => new_author
444
+ assert_equal new_author, authors(:david).reload.favorite_authors.first
445
+ end
446
+
447
+ def test_has_many_through_uses_conditions_specified_on_the_has_many_association
448
+ author = Author.first
449
+ assert author.comments.present?
450
+ assert author.nonexistant_comments.blank?
451
+ end
452
+
453
+ def test_has_many_through_uses_correct_attributes
454
+ assert_nil posts(:thinking).tags.find_by_name("General").attributes["tag_id"]
455
+ end
456
+
457
+ def test_associating_unsaved_records_with_has_many_through
458
+ saved_post = posts(:thinking)
459
+ new_tag = Tag.new(:name => "new")
460
+
461
+ saved_post.tags << new_tag
462
+ assert new_tag.persisted? #consistent with habtm!
463
+ assert saved_post.persisted?
464
+ assert saved_post.tags.include?(new_tag)
465
+
466
+ assert new_tag.persisted?
467
+ assert saved_post.reload.tags(true).include?(new_tag)
468
+
469
+
470
+ new_post = Post.new(:title => "Association replacement works!", :body => "You best believe it.")
471
+ saved_tag = tags(:general)
472
+
473
+ new_post.tags << saved_tag
474
+ assert !new_post.persisted?
475
+ assert saved_tag.persisted?
476
+ assert new_post.tags.include?(saved_tag)
477
+
478
+ new_post.save!
479
+ assert new_post.persisted?
480
+ assert new_post.reload.tags(true).include?(saved_tag)
481
+
482
+ assert !posts(:thinking).tags.build.persisted?
483
+ assert !posts(:thinking).tags.new.persisted?
484
+ end
485
+
486
+ def test_create_associate_when_adding_to_has_many_through
487
+ count = posts(:thinking).tags.count
488
+ push = Tag.create!(:name => 'pushme')
489
+ post_thinking = posts(:thinking)
490
+ assert_nothing_raised { post_thinking.tags << push }
491
+ assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
492
+ message = "Expected a Tag in tags collection, got #{wrong.class}.")
493
+ assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
494
+ message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
495
+ assert_equal(count + 1, post_thinking.reload.tags.size)
496
+ assert_equal(count + 1, post_thinking.tags(true).size)
497
+
498
+ assert_kind_of Tag, post_thinking.tags.create!(:name => 'foo')
499
+ assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
500
+ message = "Expected a Tag in tags collection, got #{wrong.class}.")
501
+ assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
502
+ message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
503
+ assert_equal(count + 2, post_thinking.reload.tags.size)
504
+ assert_equal(count + 2, post_thinking.tags(true).size)
505
+
506
+ assert_nothing_raised { post_thinking.tags.concat(Tag.create!(:name => 'abc'), Tag.create!(:name => 'def')) }
507
+ assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
508
+ message = "Expected a Tag in tags collection, got #{wrong.class}.")
509
+ assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
510
+ message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
511
+ assert_equal(count + 4, post_thinking.reload.tags.size)
512
+ assert_equal(count + 4, post_thinking.tags(true).size)
513
+
514
+ # Raises if the wrong reflection name is used to set the Edge belongs_to
515
+ assert_nothing_raised { vertices(:vertex_1).sinks << vertices(:vertex_5) }
516
+ end
517
+
518
+ def test_add_to_join_table_with_no_id
519
+ assert_nothing_raised { vertices(:vertex_1).sinks << vertices(:vertex_5) }
520
+ end
521
+
522
+ def test_has_many_through_collection_size_doesnt_load_target_if_not_loaded
523
+ author = authors(:david)
524
+ assert_equal 10, author.comments.size
525
+ assert !author.comments.loaded?
526
+ end
527
+
528
+ def test_has_many_through_collection_size_uses_counter_cache_if_it_exists
529
+ c = categories(:general)
530
+ c.categorizations_count = 100
531
+ assert_equal 100, c.categorizations.size
532
+ assert !c.categorizations.loaded?
533
+ end
534
+
535
+ def test_adding_junk_to_has_many_through_should_raise_type_mismatch
536
+ assert_raise(ActiveRecord::AssociationTypeMismatch) { posts(:thinking).tags << "Uhh what now?" }
537
+ end
538
+
539
+ def test_adding_to_has_many_through_should_return_self
540
+ tags = posts(:thinking).tags
541
+ assert_equal tags, posts(:thinking).tags.push(tags(:general))
542
+ end
543
+
544
+ def test_delete_associate_when_deleting_from_has_many_through_with_nonstandard_id
545
+ count = books(:awdr).references.count
546
+ references_before = books(:awdr).references
547
+ book = Book.create!(:name => 'Getting Real')
548
+ book_awdr = books(:awdr)
549
+ book_awdr.references << book
550
+ assert_equal(count + 1, book_awdr.references(true).size)
551
+
552
+ assert_nothing_raised { book_awdr.references.delete(book) }
553
+ assert_equal(count, book_awdr.references.size)
554
+ assert_equal(count, book_awdr.references(true).size)
555
+ assert_equal(references_before.sort, book_awdr.references.sort)
556
+ end
557
+
558
+ def test_delete_associate_when_deleting_from_has_many_through
559
+ count = posts(:thinking).tags.count
560
+ tags_before = posts(:thinking).tags.sort
561
+ tag = Tag.create!(:name => 'doomed')
562
+ post_thinking = posts(:thinking)
563
+ post_thinking.tags << tag
564
+ assert_equal(count + 1, post_thinking.taggings(true).size)
565
+ assert_equal(count + 1, post_thinking.reload.tags(true).size)
566
+ assert_not_equal(tags_before, post_thinking.tags.sort)
567
+
568
+ assert_nothing_raised { post_thinking.tags.delete(tag) }
569
+ assert_equal(count, post_thinking.tags.size)
570
+ assert_equal(count, post_thinking.tags(true).size)
571
+ assert_equal(count, post_thinking.taggings(true).size)
572
+ assert_equal(tags_before, post_thinking.tags.sort)
573
+ end
574
+
575
+ def test_delete_associate_when_deleting_from_has_many_through_with_multiple_tags
576
+ count = posts(:thinking).tags.count
577
+ tags_before = posts(:thinking).tags.sort
578
+ doomed = Tag.create!(:name => 'doomed')
579
+ doomed2 = Tag.create!(:name => 'doomed2')
580
+ quaked = Tag.create!(:name => 'quaked')
581
+ post_thinking = posts(:thinking)
582
+ post_thinking.tags << doomed << doomed2
583
+ assert_equal(count + 2, post_thinking.reload.tags(true).size)
584
+
585
+ assert_nothing_raised { post_thinking.tags.delete(doomed, doomed2, quaked) }
586
+ assert_equal(count, post_thinking.tags.size)
587
+ assert_equal(count, post_thinking.tags(true).size)
588
+ assert_equal(tags_before, post_thinking.tags.sort)
589
+ end
590
+
591
+ def test_deleting_junk_from_has_many_through_should_raise_type_mismatch
592
+ assert_raise(ActiveRecord::AssociationTypeMismatch) { posts(:thinking).tags.delete(Object.new) }
593
+ end
594
+
595
+ def test_deleting_by_fixnum_id_from_has_many_through
596
+ post = posts(:thinking)
597
+
598
+ assert_difference 'post.tags.count', -1 do
599
+ assert_equal 1, post.tags.delete(1).size
600
+ end
601
+
602
+ assert_equal 0, post.tags.size
603
+ end
604
+
605
+ def test_deleting_by_string_id_from_has_many_through
606
+ post = posts(:thinking)
607
+
608
+ assert_difference 'post.tags.count', -1 do
609
+ assert_equal 1, post.tags.delete('1').size
610
+ end
611
+
612
+ assert_equal 0, post.tags.size
613
+ end
614
+
615
+ def test_has_many_through_sum_uses_calculations
616
+ assert_nothing_raised { authors(:david).comments.sum(:post_id) }
617
+ end
618
+
619
+ def test_calculations_on_has_many_through_should_disambiguate_fields
620
+ assert_nothing_raised { authors(:david).categories.maximum(:id) }
621
+ end
622
+
623
+ def test_calculations_on_has_many_through_should_not_disambiguate_fields_unless_necessary
624
+ assert_nothing_raised { authors(:david).categories.maximum("categories.id") }
625
+ end
626
+
627
+ def test_has_many_through_has_many_with_sti
628
+ assert_equal [comments(:does_it_hurt)], authors(:david).special_post_comments
629
+ end
630
+
631
+ def test_uniq_has_many_through_should_retain_order
632
+ comment_ids = authors(:david).comments.map(&:id)
633
+ assert_equal comment_ids.sort, authors(:david).ordered_uniq_comments.map(&:id)
634
+ assert_equal comment_ids.sort.reverse, authors(:david).ordered_uniq_comments_desc.map(&:id)
635
+ end
636
+
637
+ def test_polymorphic_has_many
638
+ expected = taggings(:welcome_general)
639
+ p = Post.all.merge!(:includes => :taggings).find(posts(:welcome).id)
640
+ assert_no_queries {assert p.taggings.include?(expected)}
641
+ assert posts(:welcome).taggings.include?(taggings(:welcome_general))
642
+ end
643
+
644
+ def test_polymorphic_has_one
645
+ expected = posts(:welcome)
646
+
647
+ tagging = Tagging.all.merge!(:includes => :taggable).find(taggings(:welcome_general).id)
648
+ assert_no_queries { assert_equal expected, tagging.taggable}
649
+ end
650
+
651
+ def test_polymorphic_belongs_to
652
+ p = Post.all.merge!(:includes => {:taggings => :taggable}).find(posts(:welcome).id)
653
+ assert_no_queries {assert_equal posts(:welcome), p.taggings.first.taggable}
654
+ end
655
+
656
+ def test_preload_polymorphic_has_many_through
657
+ posts = Post.all.merge!(:order => 'posts.id').to_a
658
+ posts_with_tags = Post.all.merge!(:includes => :tags, :order => 'posts.id').to_a
659
+ assert_equal posts.length, posts_with_tags.length
660
+ posts.length.times do |i|
661
+ assert_equal posts[i].tags.length, assert_no_queries { posts_with_tags[i].tags.length }
662
+ end
663
+ end
664
+
665
+ def test_preload_polymorph_many_types
666
+ taggings = Tagging.all.merge!(:includes => :taggable, :where => ['taggable_type != ?', 'FakeModel']).to_a
667
+ assert_no_queries do
668
+ taggings.first.taggable.id
669
+ taggings[1].taggable.id
670
+ end
671
+
672
+ taggables = taggings.map(&:taggable)
673
+ assert taggables.include?(items(:dvd))
674
+ assert taggables.include?(posts(:welcome))
675
+ end
676
+
677
+ def test_preload_nil_polymorphic_belongs_to
678
+ assert_nothing_raised do
679
+ Tagging.all.merge!(:includes => :taggable, :where => ['taggable_type IS NULL']).to_a
680
+ end
681
+ end
682
+
683
+ def test_preload_polymorphic_has_many
684
+ posts = Post.all.merge!(:order => 'posts.id').to_a
685
+ posts_with_taggings = Post.all.merge!(:includes => :taggings, :order => 'posts.id').to_a
686
+ assert_equal posts.length, posts_with_taggings.length
687
+ posts.length.times do |i|
688
+ assert_equal posts[i].taggings.length, assert_no_queries { posts_with_taggings[i].taggings.length }
689
+ end
690
+ end
691
+
692
+ def test_belongs_to_shared_parent
693
+ comments = Comment.all.merge!(:includes => :post, :where => 'post_id = 1').to_a
694
+ assert_no_queries do
695
+ assert_equal comments.first.post, comments[1].post
696
+ end
697
+ end
698
+
699
+ def test_has_many_through_include_uses_array_include_after_loaded
700
+ david = authors(:david)
701
+ david.categories.load_target
702
+
703
+ category = david.categories.first
704
+
705
+ assert_no_queries do
706
+ assert david.categories.loaded?
707
+ assert david.categories.include?(category)
708
+ end
709
+ end
710
+
711
+ def test_has_many_through_include_checks_if_record_exists_if_target_not_loaded
712
+ david = authors(:david)
713
+ category = david.categories.first
714
+
715
+ david.reload
716
+ assert ! david.categories.loaded?
717
+ assert_queries(1) do
718
+ assert david.categories.include?(category)
719
+ end
720
+ assert ! david.categories.loaded?
721
+ end
722
+
723
+ def test_has_many_through_include_returns_false_for_non_matching_record_to_verify_scoping
724
+ david = authors(:david)
725
+ category = Category.create!(:name => 'Not Associated')
726
+
727
+ assert ! david.categories.loaded?
728
+ assert ! david.categories.include?(category)
729
+ end
730
+
731
+ def test_has_many_through_goes_through_all_sti_classes
732
+ sub_sti_post = SubStiPost.create!(:title => 'test', :body => 'test', :author_id => 1)
733
+ new_comment = sub_sti_post.comments.create(:body => 'test')
734
+
735
+ assert_equal [9, 10, new_comment.id], authors(:david).sti_post_comments.map(&:id).sort
736
+ end
737
+
738
+ def test_has_many_with_pluralize_table_names_false
739
+ aircraft = Aircraft.create!(:name => "Airbus 380")
740
+ engine = Engine.create!(:car_id => aircraft.id)
741
+ assert_equal aircraft.engines, [engine]
742
+ end
743
+
744
+ private
745
+ # create dynamic Post models to allow different dependency options
746
+ def find_post_with_dependency(post_id, association, association_name, dependency)
747
+ class_name = "PostWith#{association.to_s.classify}#{dependency.to_s.classify}"
748
+ Post.find(post_id).update_columns type: class_name
749
+ klass = Object.const_set(class_name, Class.new(ActiveRecord::Base))
750
+ klass.table_name = 'posts'
751
+ klass.send(association, association_name, :as => :taggable, :dependent => dependency)
752
+ klass.find(post_id)
753
+ end
754
+ end